1use crate::constants::*;
2use crate::internal::OperationError;
3use serde::{Deserialize, Serialize};
4use std::convert::Infallible;
5use std::fmt;
6use std::str::FromStr;
7use utoipa::ToSchema;
8
9pub use smartstring::alias::String as AttrString;
10
11#[derive(
12 Serialize, Deserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, Default, ToSchema,
13)]
14#[cfg_attr(test, derive(enum_iterator::Sequence))]
15#[serde(rename_all = "lowercase", from = "String", into = "AttrString")]
16pub enum Attribute {
17 Account,
18 AccountExpire,
19 AccountValidFrom,
20 AccountSoftlockExpire,
21 AcpCreateAttr,
22 AcpCreateClass,
23 AcpEnable,
24 AcpModifyClass,
25 AcpModifyPresentClass,
26 AcpModifyRemoveClass,
27 AcpModifyPresentAttr,
28 AcpModifyRemovedAttr,
29 AcpReceiver,
30 AcpReceiverGroup,
31 AcpSearchAttr,
32 AcpTargetScope,
33 ApiTokenSession,
34 ApplicationPassword,
35 ApplicationUrl,
36 AttestedPasskeys,
37 #[default]
38 Attr,
39 AttributeName,
40 AttributeType,
41 AuthSessionExpiry,
42 AuthPasswordMinimumLength,
43 BadlistPassword,
44 Certificate,
45 CascadeDeleted,
46 Claim,
47 Class,
48 ClassName,
49 Cn,
50 CookiePrivateKey,
51 CreatedAtCid,
52 CredentialUpdateIntentToken,
53 CredentialTypeMinimum,
54 DeniedName,
55 DeleteAfter,
56 Description,
57 DirectMemberOf,
58 DisplayName,
59 Dn,
60 Domain,
61 DomainAllowEasterEggs,
62 DomainAllowAccountRecovery,
63 DomainDevelopmentTaint,
64 DomainDisplayName,
65 DomainLdapBasedn,
66 DomainName,
67 DomainSsid,
68 DomainTokenKey,
69 DomainUuid,
70 DynGroup,
71 DynGroupFilter,
72 DynMember,
73 Enabled,
74 Email,
75 EmailAlternative,
76 EmailPrimary,
77 EntryDn,
78 EntryManagedBy,
79 EntryUuid,
80 Es256PrivateKeyDer,
81 Excludes,
82 FernetPrivateKeyStr,
83 Gecos,
84 GidNumber,
85 GrantUiHint,
86 Group,
87 HmacNameHistory,
88 HomeDirectory,
89 IdVerificationEcKey,
90 Image,
91 Index,
92 Indexed,
93 InMemoriam,
94 IpaNtHash,
95 IpaSshPubKey,
96 JwsEs256PrivateKey,
97 KeyActionRotate,
98 KeyActionRevoke,
99 KeyActionImportJwsEs256,
100 KeyActionImportJwsRs256,
101 KeyInternalData,
102 KeyProvider,
103 LastModifiedCid,
104 LdapAllowUnixPwBind,
105 LdapEmailAddress,
107 LdapKeys,
109 LdapMaxQueryableAttrs,
110 LegalName,
111 LimitSearchMaxResults,
112 LimitSearchMaxFilterTest,
113 LinkedGroup,
114 LoginShell,
115 Mail,
116 MailDestination,
117 May,
118 Member,
119 MemberCreateOnce,
120 MemberOf,
121 MessageTemplate,
122 MultiValue,
123 Must,
124 Name,
125 NameHistory,
126 NoIndex,
127 NsUniqueId,
128 NsAccountLock,
129 OAuth2AllowInsecureClientDisablePkce,
130 OAuth2AllowLocalhostRedirect,
131 OAuth2AuthorisationEndpoint,
132 OAuth2ClientId,
133 OAuth2ClientSecret,
134 OAuth2ConsentScopeMap,
135 OAuth2DeviceFlowEnable,
136 OAuth2JwtLegacyCryptoEnable,
137 OAuth2PreferShortUsername,
138 OAuth2RefreshTokenExpiry,
139 OAuth2RequestScopes,
140 OAuth2RsBasicSecret,
141 OAuth2RsClaimMap,
142 OAuth2RsImplicitScopes,
143 OAuth2RsName,
144 OAuth2RsOrigin,
145 OAuth2RsOriginLanding,
146 OAuth2RsScopeMap,
147 OAuth2RsSupScopeMap,
148 OAuth2RsTokenKey,
149 OAuth2Session,
150 OAuth2StrictRedirectUri,
151 OAuth2TokenEndpoint,
152 OAuth2TokenIntrospectEndpoint,
153 OAuth2AccountCredentialUuid,
154 OAuth2AccountProvider,
155 OAuth2AccountUniqueUserId,
156 OAuth2AccountUniqueUserSub,
157 OAuth2ConsentPromptEnable,
158 ObjectClass,
159 OtherNoIndex,
160 PassKeys,
161 PasswordImport,
162 PasswordChangedTime,
163 PatchLevel,
164 Phantom,
165 PrimaryCredential,
166 PrivateCookieKey,
167 PrivilegeExpiry,
168 RadiusSecret,
169 RecycledDirectMemberOf,
170 Refers,
171 Replicated,
172 Rs256PrivateKeyDer,
173 S256,
174 #[serde(rename = "schemas")]
176 ScimSchemas,
177 Scope,
178 SendAfter,
179 SentAt,
180 SourceUuid,
181 Spn,
182 LdapSshPublicKey,
184 SshPublicKey,
186 SudoHost,
187 Supplements,
188 SystemSupplements,
189 SyncAllowed,
190 SyncClass,
191 SyncCookie,
192 SyncCredentialPortal,
193 SyncExternalId,
194 SyncParentUuid,
195 SyncTokenSession,
196 SyncYieldAuthority,
197 Syntax,
198 SystemExcludes,
199 SystemMay,
200 SystemMust,
201 Term,
202 TotpImport,
203 Uid,
204 UidNumber,
205 Unique,
206 UnixPassword,
207 UnixPasswordImport,
208 UserAuthTokenSession,
209 UserId,
210 UserPassword,
211 Uuid,
212 Version,
213 WebauthnAttestationCaList,
214 AllowPrimaryCredFallback,
215
216 #[cfg(any(debug_assertions, test, feature = "test"))]
217 NonExist,
218 #[cfg(any(debug_assertions, test, feature = "test"))]
219 TestAttr,
220 #[cfg(test)]
221 TestAttrA,
222 #[cfg(test)]
223 TestAttrB,
224 #[cfg(test)]
225 TestAttrC,
226 #[cfg(test)]
227 TestAttrD,
228 #[cfg(any(debug_assertions, test, feature = "test"))]
229 TestNumber,
230 #[cfg(any(debug_assertions, test, feature = "test"))]
231 Extra,
232 #[cfg(any(debug_assertions, test, feature = "test"))]
233 TestNotAllowed,
234
235 #[cfg(not(test))]
236 #[schema(value_type = String)]
237 Custom(AttrString),
238}
239
240impl AsRef<str> for Attribute {
241 fn as_ref(&self) -> &str {
242 self.as_str()
243 }
244}
245
246impl AsRef<Attribute> for Attribute {
247 fn as_ref(&self) -> &Attribute {
248 self
249 }
250}
251
252impl TryFrom<&AttrString> for Attribute {
253 type Error = OperationError;
254
255 fn try_from(value: &AttrString) -> Result<Self, Self::Error> {
256 Ok(Attribute::inner_from_str(value.as_str()))
257 }
258}
259
260impl From<&str> for Attribute {
261 fn from(value: &str) -> Self {
262 Self::inner_from_str(value)
263 }
264}
265
266impl From<String> for Attribute {
267 fn from(value: String) -> Self {
268 Self::inner_from_str(value.as_str())
269 }
270}
271
272impl<'a> From<&'a Attribute> for &'a str {
273 fn from(val: &'a Attribute) -> Self {
274 val.as_str()
275 }
276}
277
278impl From<Attribute> for AttrString {
279 fn from(val: Attribute) -> Self {
280 AttrString::from(val.as_str())
281 }
282}
283
284impl FromStr for Attribute {
285 type Err = Infallible;
286
287 fn from_str(value: &str) -> Result<Self, Self::Err> {
288 Ok(Self::inner_from_str(value))
289 }
290}
291
292impl Attribute {
293 pub fn as_str(&self) -> &str {
294 match self {
295 Attribute::Account => ATTR_ACCOUNT,
296 Attribute::AccountExpire => ATTR_ACCOUNT_EXPIRE,
297 Attribute::AccountValidFrom => ATTR_ACCOUNT_VALID_FROM,
298 Attribute::AccountSoftlockExpire => ATTR_ACCOUNT_SOFTLOCK_EXPIRE,
299 Attribute::AcpCreateAttr => ATTR_ACP_CREATE_ATTR,
300 Attribute::AcpCreateClass => ATTR_ACP_CREATE_CLASS,
301 Attribute::AcpEnable => ATTR_ACP_ENABLE,
302 Attribute::AcpModifyClass => ATTR_ACP_MODIFY_CLASS,
303 Attribute::AcpModifyPresentClass => ATTR_ACP_MODIFY_PRESENT_CLASS,
304 Attribute::AcpModifyRemoveClass => ATTR_ACP_MODIFY_REMOVE_CLASS,
305 Attribute::AcpModifyPresentAttr => ATTR_ACP_MODIFY_PRESENTATTR,
306 Attribute::AcpModifyRemovedAttr => ATTR_ACP_MODIFY_REMOVEDATTR,
307 Attribute::AcpReceiver => ATTR_ACP_RECEIVER,
308 Attribute::AcpReceiverGroup => ATTR_ACP_RECEIVER_GROUP,
309 Attribute::AcpSearchAttr => ATTR_ACP_SEARCH_ATTR,
310 Attribute::AcpTargetScope => ATTR_ACP_TARGET_SCOPE,
311 Attribute::AllowPrimaryCredFallback => ATTR_ALLOW_PRIMARY_CRED_FALLBACK,
312 Attribute::ApiTokenSession => ATTR_API_TOKEN_SESSION,
313 Attribute::ApplicationPassword => ATTR_APPLICATION_PASSWORD,
314 Attribute::ApplicationUrl => ATTR_APPLICATION_URL,
315 Attribute::AttestedPasskeys => ATTR_ATTESTED_PASSKEYS,
316 Attribute::Attr => ATTR_ATTR,
317 Attribute::AttributeName => ATTR_ATTRIBUTENAME,
318 Attribute::AttributeType => ATTR_ATTRIBUTETYPE,
319 Attribute::AuthSessionExpiry => ATTR_AUTH_SESSION_EXPIRY,
320 Attribute::AuthPasswordMinimumLength => ATTR_AUTH_PASSWORD_MINIMUM_LENGTH,
321 Attribute::BadlistPassword => ATTR_BADLIST_PASSWORD,
322 Attribute::Certificate => ATTR_CERTIFICATE,
323 Attribute::CascadeDeleted => ATTR_CASCADE_DELETED,
324 Attribute::Claim => ATTR_CLAIM,
325 Attribute::Class => ATTR_CLASS,
326 Attribute::ClassName => ATTR_CLASSNAME,
327 Attribute::Cn => ATTR_CN,
328 Attribute::CookiePrivateKey => ATTR_COOKIE_PRIVATE_KEY,
329 Attribute::CreatedAtCid => ATTR_CREATED_AT_CID,
330 Attribute::CredentialUpdateIntentToken => ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
331 Attribute::CredentialTypeMinimum => ATTR_CREDENTIAL_TYPE_MINIMUM,
332 Attribute::DeniedName => ATTR_DENIED_NAME,
333 Attribute::DeleteAfter => ATTR_DELETE_AFTER,
334 Attribute::Description => ATTR_DESCRIPTION,
335 Attribute::DirectMemberOf => ATTR_DIRECTMEMBEROF,
336 Attribute::DisplayName => ATTR_DISPLAYNAME,
337 Attribute::Dn => ATTR_DN,
338 Attribute::Domain => ATTR_DOMAIN,
339 Attribute::DomainAllowEasterEggs => ATTR_DOMAIN_ALLOW_EASTER_EGGS,
340 Attribute::DomainAllowAccountRecovery => ATTR_DOMAIN_ALLOW_ACCOUNT_RECOVERY,
341 Attribute::DomainDevelopmentTaint => ATTR_DOMAIN_DEVELOPMENT_TAINT,
342 Attribute::DomainDisplayName => ATTR_DOMAIN_DISPLAY_NAME,
343 Attribute::DomainLdapBasedn => ATTR_DOMAIN_LDAP_BASEDN,
344 Attribute::DomainName => ATTR_DOMAIN_NAME,
345 Attribute::DomainSsid => ATTR_DOMAIN_SSID,
346 Attribute::DomainTokenKey => ATTR_DOMAIN_TOKEN_KEY,
347 Attribute::DomainUuid => ATTR_DOMAIN_UUID,
348 Attribute::DynGroup => ATTR_DYNGROUP,
349 Attribute::DynGroupFilter => ATTR_DYNGROUP_FILTER,
350 Attribute::DynMember => ATTR_DYNMEMBER,
351 Attribute::Enabled => ATTR_ENABLED,
352 Attribute::Email => ATTR_EMAIL,
353 Attribute::EmailAlternative => ATTR_EMAIL_ALTERNATIVE,
354 Attribute::EmailPrimary => ATTR_EMAIL_PRIMARY,
355 Attribute::EntryDn => ATTR_ENTRYDN,
356 Attribute::EntryManagedBy => ATTR_ENTRY_MANAGED_BY,
357 Attribute::EntryUuid => ATTR_ENTRYUUID,
358 Attribute::Es256PrivateKeyDer => ATTR_ES256_PRIVATE_KEY_DER,
359 Attribute::Excludes => ATTR_EXCLUDES,
360 Attribute::FernetPrivateKeyStr => ATTR_FERNET_PRIVATE_KEY_STR,
361 Attribute::Gecos => ATTR_GECOS,
362 Attribute::GidNumber => ATTR_GIDNUMBER,
363 Attribute::GrantUiHint => ATTR_GRANT_UI_HINT,
364 Attribute::Group => ATTR_GROUP,
365 Attribute::HmacNameHistory => ATTR_HMAC_NAME_HISTORY,
366 Attribute::HomeDirectory => ATTR_HOME_DIRECTORY,
367 Attribute::IdVerificationEcKey => ATTR_ID_VERIFICATION_ECKEY,
368 Attribute::Image => ATTR_IMAGE,
369 Attribute::Index => ATTR_INDEX,
370 Attribute::Indexed => ATTR_INDEXED,
371 Attribute::InMemoriam => ATTR_IN_MEMORIAM,
372 Attribute::IpaNtHash => ATTR_IPANTHASH,
373 Attribute::IpaSshPubKey => ATTR_IPASSHPUBKEY,
374 Attribute::JwsEs256PrivateKey => ATTR_JWS_ES256_PRIVATE_KEY,
375 Attribute::KeyActionRotate => ATTR_KEY_ACTION_ROTATE,
376 Attribute::KeyActionRevoke => ATTR_KEY_ACTION_REVOKE,
377 Attribute::KeyActionImportJwsEs256 => ATTR_KEY_ACTION_IMPORT_JWS_ES256,
378 Attribute::KeyActionImportJwsRs256 => ATTR_KEY_ACTION_IMPORT_JWS_RS256,
379 Attribute::KeyInternalData => ATTR_KEY_INTERNAL_DATA,
380 Attribute::KeyProvider => ATTR_KEY_PROVIDER,
381 Attribute::LastModifiedCid => ATTR_LAST_MODIFIED_CID,
382 Attribute::LdapAllowUnixPwBind => ATTR_LDAP_ALLOW_UNIX_PW_BIND,
383 Attribute::LdapEmailAddress => ATTR_LDAP_EMAIL_ADDRESS,
384 Attribute::LdapKeys => ATTR_LDAP_KEYS,
385 Attribute::LdapMaxQueryableAttrs => ATTR_LDAP_MAX_QUERYABLE_ATTRS,
386 Attribute::LdapSshPublicKey => ATTR_LDAP_SSHPUBLICKEY,
387 Attribute::LegalName => ATTR_LEGALNAME,
388 Attribute::LimitSearchMaxResults => ATTR_LIMIT_SEARCH_MAX_RESULTS,
389 Attribute::LimitSearchMaxFilterTest => ATTR_LIMIT_SEARCH_MAX_FILTER_TEST,
390 Attribute::LinkedGroup => ATTR_LINKEDGROUP,
391 Attribute::LoginShell => ATTR_LOGINSHELL,
392 Attribute::Mail => ATTR_MAIL,
393 Attribute::MailDestination => ATTR_MAIL_DESTINATION,
394 Attribute::May => ATTR_MAY,
395 Attribute::Member => ATTR_MEMBER,
396 Attribute::MemberCreateOnce => ATTR_MEMBER_CREATE_ONCE,
397 Attribute::MemberOf => ATTR_MEMBEROF,
398 Attribute::MessageTemplate => ATTR_MESSAGE_TEMPLATE,
399 Attribute::MultiValue => ATTR_MULTIVALUE,
400 Attribute::Must => ATTR_MUST,
401 Attribute::Name => ATTR_NAME,
402 Attribute::NameHistory => ATTR_NAME_HISTORY,
403 Attribute::NoIndex => ATTR_NO_INDEX,
404 Attribute::NsUniqueId => ATTR_NSUNIQUEID,
405 Attribute::NsAccountLock => ATTR_NSACCOUNTLOCK,
406 Attribute::OAuth2AllowInsecureClientDisablePkce => {
407 ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE
408 }
409 Attribute::OAuth2AllowLocalhostRedirect => ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT,
410 Attribute::OAuth2AuthorisationEndpoint => ATTR_OAUTH2_AUTHORISATION_ENDPOINT,
411 Attribute::OAuth2ClientId => ATTR_OAUTH2_CLIENT_ID,
412 Attribute::OAuth2ClientSecret => ATTR_OAUTH2_CLIENT_SECRET,
413 Attribute::OAuth2ConsentScopeMap => ATTR_OAUTH2_CONSENT_SCOPE_MAP,
414 Attribute::OAuth2DeviceFlowEnable => ATTR_OAUTH2_DEVICE_FLOW_ENABLE,
415 Attribute::OAuth2JwtLegacyCryptoEnable => ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE,
416 Attribute::OAuth2PreferShortUsername => ATTR_OAUTH2_PREFER_SHORT_USERNAME,
417 Attribute::OAuth2RefreshTokenExpiry => ATTR_OAUTH2_REFRESH_TOKEN_EXPIRY,
418 Attribute::OAuth2RequestScopes => ATTR_OAUTH2_REQUEST_SCOPES,
419 Attribute::OAuth2RsBasicSecret => ATTR_OAUTH2_RS_BASIC_SECRET,
420 Attribute::OAuth2RsClaimMap => ATTR_OAUTH2_RS_CLAIM_MAP,
421 Attribute::OAuth2RsImplicitScopes => ATTR_OAUTH2_RS_IMPLICIT_SCOPES,
422 Attribute::OAuth2RsName => ATTR_OAUTH2_RS_NAME,
423 Attribute::OAuth2RsOrigin => ATTR_OAUTH2_RS_ORIGIN,
424 Attribute::OAuth2RsOriginLanding => ATTR_OAUTH2_RS_ORIGIN_LANDING,
425 Attribute::OAuth2RsScopeMap => ATTR_OAUTH2_RS_SCOPE_MAP,
426 Attribute::OAuth2RsSupScopeMap => ATTR_OAUTH2_RS_SUP_SCOPE_MAP,
427 Attribute::OAuth2RsTokenKey => ATTR_OAUTH2_RS_TOKEN_KEY,
428 Attribute::OAuth2Session => ATTR_OAUTH2_SESSION,
429 Attribute::OAuth2StrictRedirectUri => ATTR_OAUTH2_STRICT_REDIRECT_URI,
430 Attribute::OAuth2TokenEndpoint => ATTR_OAUTH2_TOKEN_ENDPOINT,
431 Attribute::OAuth2TokenIntrospectEndpoint => ATTR_OAUTH2_TOKEN_INTROSPECT_ENDPOINT,
432 Attribute::OAuth2AccountCredentialUuid => ATTR_OAUTH2_ACCOUNT_CREDENTIAL_UUID,
433 Attribute::OAuth2AccountProvider => ATTR_OAUTH2_ACCOUNT_PROVIDER,
434 Attribute::OAuth2AccountUniqueUserId => ATTR_OAUTH2_ACCOUNT_UNIQUE_USER_ID,
435 Attribute::OAuth2AccountUniqueUserSub => ATTR_OAUTH2_ACCOUNT_UNIQUE_USER_SUB,
436 Attribute::OAuth2ConsentPromptEnable => ATTR_OAUTH2_CONSENT_PROMPT_ENABLE,
437 Attribute::ObjectClass => ATTR_OBJECTCLASS,
438 Attribute::OtherNoIndex => ATTR_OTHER_NO_INDEX,
439 Attribute::PassKeys => ATTR_PASSKEYS,
440 Attribute::PasswordChangedTime => ATTR_PWD_CHANGED_TIME,
441 Attribute::PasswordImport => ATTR_PASSWORD_IMPORT,
442 Attribute::PatchLevel => ATTR_PATCH_LEVEL,
443 Attribute::Phantom => ATTR_PHANTOM,
444 Attribute::PrimaryCredential => ATTR_PRIMARY_CREDENTIAL,
445 Attribute::PrivateCookieKey => ATTR_PRIVATE_COOKIE_KEY,
446 Attribute::PrivilegeExpiry => ATTR_PRIVILEGE_EXPIRY,
447 Attribute::RadiusSecret => ATTR_RADIUS_SECRET,
448 Attribute::RecycledDirectMemberOf => ATTR_RECYCLEDDIRECTMEMBEROF,
449 Attribute::Refers => ATTR_REFERS,
450 Attribute::Replicated => ATTR_REPLICATED,
451 Attribute::Rs256PrivateKeyDer => ATTR_RS256_PRIVATE_KEY_DER,
452 Attribute::S256 => ATTR_S256,
453 Attribute::Scope => ATTR_SCOPE,
454 Attribute::ScimSchemas => ATTR_SCIM_SCHEMAS,
455 Attribute::SendAfter => ATTR_SEND_AFTER,
456 Attribute::SentAt => ATTR_SENT_AT,
457 Attribute::SourceUuid => ATTR_SOURCE_UUID,
458 Attribute::Spn => ATTR_SPN,
459 Attribute::SshPublicKey => ATTR_SSH_PUBLICKEY,
460 Attribute::SudoHost => ATTR_SUDOHOST,
461 Attribute::Supplements => ATTR_SUPPLEMENTS,
462 Attribute::SyncAllowed => ATTR_SYNC_ALLOWED,
463 Attribute::SyncClass => ATTR_SYNC_CLASS,
464 Attribute::SyncCookie => ATTR_SYNC_COOKIE,
465 Attribute::SyncCredentialPortal => ATTR_SYNC_CREDENTIAL_PORTAL,
466 Attribute::SyncExternalId => ATTR_SYNC_EXTERNAL_ID,
467 Attribute::SyncParentUuid => ATTR_SYNC_PARENT_UUID,
468 Attribute::SyncTokenSession => ATTR_SYNC_TOKEN_SESSION,
469 Attribute::SyncYieldAuthority => ATTR_SYNC_YIELD_AUTHORITY,
470 Attribute::Syntax => ATTR_SYNTAX,
471 Attribute::SystemExcludes => ATTR_SYSTEMEXCLUDES,
472 Attribute::SystemMay => ATTR_SYSTEMMAY,
473 Attribute::SystemMust => ATTR_SYSTEMMUST,
474 Attribute::SystemSupplements => ATTR_SYSTEMSUPPLEMENTS,
475 Attribute::Term => ATTR_TERM,
476 Attribute::TotpImport => ATTR_TOTP_IMPORT,
477 Attribute::Uid => ATTR_UID,
478 Attribute::UidNumber => ATTR_UIDNUMBER,
479 Attribute::Unique => ATTR_UNIQUE,
480 Attribute::UnixPassword => ATTR_UNIX_PASSWORD,
481 Attribute::UnixPasswordImport => ATTR_UNIX_PASSWORD_IMPORT,
482 Attribute::UserAuthTokenSession => ATTR_USER_AUTH_TOKEN_SESSION,
483 Attribute::UserId => ATTR_USERID,
484 Attribute::UserPassword => ATTR_USERPASSWORD,
485 Attribute::Uuid => ATTR_UUID,
486 Attribute::Version => ATTR_VERSION,
487 Attribute::WebauthnAttestationCaList => ATTR_WEBAUTHN_ATTESTATION_CA_LIST,
488
489 #[cfg(any(debug_assertions, test, feature = "test"))]
490 Attribute::NonExist => TEST_ATTR_NON_EXIST,
491 #[cfg(any(debug_assertions, test, feature = "test"))]
492 Attribute::TestAttr => TEST_ATTR_TEST_ATTR,
493
494 #[cfg(test)]
495 Attribute::TestAttrA => TEST_ATTR_TEST_ATTR_A,
496 #[cfg(test)]
497 Attribute::TestAttrB => TEST_ATTR_TEST_ATTR_B,
498 #[cfg(test)]
499 Attribute::TestAttrC => TEST_ATTR_TEST_ATTR_C,
500 #[cfg(test)]
501 Attribute::TestAttrD => TEST_ATTR_TEST_ATTR_D,
502
503 #[cfg(any(debug_assertions, test, feature = "test"))]
504 Attribute::Extra => TEST_ATTR_EXTRA,
505 #[cfg(any(debug_assertions, test, feature = "test"))]
506 Attribute::TestNumber => TEST_ATTR_NUMBER,
507 #[cfg(any(debug_assertions, test, feature = "test"))]
508 Attribute::TestNotAllowed => TEST_ATTR_NOTALLOWED,
509
510 #[cfg(not(test))]
511 Attribute::Custom(value) => value.as_str(),
512 }
513 }
514
515 #[allow(clippy::should_implement_trait)]
517 fn inner_from_str(value: &str) -> Self {
518 match value.to_lowercase().as_str() {
521 ATTR_ACCOUNT => Attribute::Account,
522 ATTR_ACCOUNT_EXPIRE => Attribute::AccountExpire,
523 ATTR_ACCOUNT_VALID_FROM => Attribute::AccountValidFrom,
524 ATTR_ACCOUNT_SOFTLOCK_EXPIRE => Attribute::AccountSoftlockExpire,
525 ATTR_ACP_CREATE_ATTR => Attribute::AcpCreateAttr,
526 ATTR_ACP_CREATE_CLASS => Attribute::AcpCreateClass,
527 ATTR_ACP_ENABLE => Attribute::AcpEnable,
528 ATTR_ACP_MODIFY_CLASS => Attribute::AcpModifyClass,
529 ATTR_ACP_MODIFY_PRESENT_CLASS => Attribute::AcpModifyPresentClass,
530 ATTR_ACP_MODIFY_REMOVE_CLASS => Attribute::AcpModifyRemoveClass,
531 ATTR_ACP_MODIFY_PRESENTATTR => Attribute::AcpModifyPresentAttr,
532 ATTR_ACP_MODIFY_REMOVEDATTR => Attribute::AcpModifyRemovedAttr,
533 ATTR_ACP_RECEIVER => Attribute::AcpReceiver,
534 ATTR_ACP_RECEIVER_GROUP => Attribute::AcpReceiverGroup,
535 ATTR_ACP_SEARCH_ATTR => Attribute::AcpSearchAttr,
536 ATTR_ACP_TARGET_SCOPE => Attribute::AcpTargetScope,
537 ATTR_ALLOW_PRIMARY_CRED_FALLBACK => Attribute::AllowPrimaryCredFallback,
538 ATTR_API_TOKEN_SESSION => Attribute::ApiTokenSession,
539 ATTR_APPLICATION_PASSWORD => Attribute::ApplicationPassword,
540 ATTR_APPLICATION_URL => Attribute::ApplicationUrl,
541 ATTR_ATTESTED_PASSKEYS => Attribute::AttestedPasskeys,
542 ATTR_ATTR => Attribute::Attr,
543 ATTR_ATTRIBUTENAME => Attribute::AttributeName,
544 ATTR_ATTRIBUTETYPE => Attribute::AttributeType,
545 ATTR_AUTH_SESSION_EXPIRY => Attribute::AuthSessionExpiry,
546 ATTR_AUTH_PASSWORD_MINIMUM_LENGTH => Attribute::AuthPasswordMinimumLength,
547 ATTR_BADLIST_PASSWORD => Attribute::BadlistPassword,
548 ATTR_CERTIFICATE => Attribute::Certificate,
549 ATTR_CASCADE_DELETED => Attribute::CascadeDeleted,
550 ATTR_CLAIM => Attribute::Claim,
551 ATTR_CLASS => Attribute::Class,
552 ATTR_CLASSNAME => Attribute::ClassName,
553 ATTR_CN => Attribute::Cn,
554 ATTR_COOKIE_PRIVATE_KEY => Attribute::CookiePrivateKey,
555 ATTR_CREATED_AT_CID => Attribute::CreatedAtCid,
556 ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN => Attribute::CredentialUpdateIntentToken,
557 ATTR_CREDENTIAL_TYPE_MINIMUM => Attribute::CredentialTypeMinimum,
558 ATTR_DENIED_NAME => Attribute::DeniedName,
559 ATTR_DELETE_AFTER => Attribute::DeleteAfter,
560 ATTR_DESCRIPTION => Attribute::Description,
561 ATTR_DIRECTMEMBEROF => Attribute::DirectMemberOf,
562 ATTR_DISPLAYNAME => Attribute::DisplayName,
563 ATTR_DN => Attribute::Dn,
564 ATTR_DOMAIN => Attribute::Domain,
565 ATTR_DOMAIN_ALLOW_EASTER_EGGS => Attribute::DomainAllowEasterEggs,
566 ATTR_DOMAIN_ALLOW_ACCOUNT_RECOVERY => Attribute::DomainAllowAccountRecovery,
567 ATTR_DOMAIN_DISPLAY_NAME => Attribute::DomainDisplayName,
568 ATTR_DOMAIN_DEVELOPMENT_TAINT => Attribute::DomainDevelopmentTaint,
569 ATTR_DOMAIN_LDAP_BASEDN => Attribute::DomainLdapBasedn,
570 ATTR_DOMAIN_NAME => Attribute::DomainName,
571 ATTR_DOMAIN_SSID => Attribute::DomainSsid,
572 ATTR_DOMAIN_TOKEN_KEY => Attribute::DomainTokenKey,
573 ATTR_DOMAIN_UUID => Attribute::DomainUuid,
574 ATTR_DYNGROUP => Attribute::DynGroup,
575 ATTR_DYNGROUP_FILTER => Attribute::DynGroupFilter,
576 ATTR_DYNMEMBER => Attribute::DynMember,
577 ATTR_ENABLED => Attribute::Enabled,
578 ATTR_EMAIL => Attribute::Email,
579 ATTR_EMAIL_ALTERNATIVE => Attribute::EmailAlternative,
580 ATTR_EMAIL_PRIMARY => Attribute::EmailPrimary,
581 ATTR_ENTRYDN => Attribute::EntryDn,
582 ATTR_ENTRY_MANAGED_BY => Attribute::EntryManagedBy,
583 ATTR_ENTRYUUID => Attribute::EntryUuid,
584 ATTR_ES256_PRIVATE_KEY_DER => Attribute::Es256PrivateKeyDer,
585 ATTR_EXCLUDES => Attribute::Excludes,
586 ATTR_FERNET_PRIVATE_KEY_STR => Attribute::FernetPrivateKeyStr,
587 ATTR_GECOS => Attribute::Gecos,
588 ATTR_GIDNUMBER => Attribute::GidNumber,
589 ATTR_GRANT_UI_HINT => Attribute::GrantUiHint,
590 ATTR_GROUP => Attribute::Group,
591 ATTR_HMAC_NAME_HISTORY => Attribute::HmacNameHistory,
592 ATTR_HOME_DIRECTORY => Attribute::HomeDirectory,
593 ATTR_ID_VERIFICATION_ECKEY => Attribute::IdVerificationEcKey,
594 ATTR_IMAGE => Attribute::Image,
595 ATTR_INDEX => Attribute::Index,
596 ATTR_INDEXED => Attribute::Indexed,
597 ATTR_IN_MEMORIAM => Attribute::InMemoriam,
598 ATTR_IPANTHASH => Attribute::IpaNtHash,
599 ATTR_IPASSHPUBKEY => Attribute::IpaSshPubKey,
600 ATTR_JWS_ES256_PRIVATE_KEY => Attribute::JwsEs256PrivateKey,
601 ATTR_KEY_ACTION_ROTATE => Attribute::KeyActionRotate,
602 ATTR_KEY_ACTION_REVOKE => Attribute::KeyActionRevoke,
603 ATTR_KEY_ACTION_IMPORT_JWS_ES256 => Attribute::KeyActionImportJwsEs256,
604 ATTR_KEY_ACTION_IMPORT_JWS_RS256 => Attribute::KeyActionImportJwsRs256,
605 ATTR_KEY_INTERNAL_DATA => Attribute::KeyInternalData,
606 ATTR_KEY_PROVIDER => Attribute::KeyProvider,
607 ATTR_LAST_MODIFIED_CID => Attribute::LastModifiedCid,
608 ATTR_LDAP_ALLOW_UNIX_PW_BIND => Attribute::LdapAllowUnixPwBind,
609 ATTR_LDAP_EMAIL_ADDRESS => Attribute::LdapEmailAddress,
610 ATTR_LDAP_KEYS => Attribute::LdapKeys,
611 ATTR_LDAP_MAX_QUERYABLE_ATTRS => Attribute::LdapMaxQueryableAttrs,
612 ATTR_SSH_PUBLICKEY => Attribute::SshPublicKey,
613 ATTR_LEGALNAME => Attribute::LegalName,
614 ATTR_LINKEDGROUP => Attribute::LinkedGroup,
615 ATTR_LOGINSHELL => Attribute::LoginShell,
616 ATTR_LIMIT_SEARCH_MAX_RESULTS => Attribute::LimitSearchMaxResults,
617 ATTR_LIMIT_SEARCH_MAX_FILTER_TEST => Attribute::LimitSearchMaxFilterTest,
618 ATTR_MAIL => Attribute::Mail,
619 ATTR_MAIL_DESTINATION => Attribute::MailDestination,
620 ATTR_MAY => Attribute::May,
621 ATTR_MEMBER => Attribute::Member,
622 ATTR_MEMBER_CREATE_ONCE => Attribute::MemberCreateOnce,
623 ATTR_MEMBEROF => Attribute::MemberOf,
624 ATTR_MESSAGE_TEMPLATE => Attribute::MessageTemplate,
625 ATTR_MULTIVALUE => Attribute::MultiValue,
626 ATTR_MUST => Attribute::Must,
627 ATTR_NAME => Attribute::Name,
628 ATTR_NAME_HISTORY => Attribute::NameHistory,
629 ATTR_NO_INDEX => Attribute::NoIndex,
630 ATTR_NSUNIQUEID => Attribute::NsUniqueId,
631 ATTR_NSACCOUNTLOCK => Attribute::NsAccountLock,
632 ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE => {
633 Attribute::OAuth2AllowInsecureClientDisablePkce
634 }
635 ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT => Attribute::OAuth2AllowLocalhostRedirect,
636 ATTR_OAUTH2_AUTHORISATION_ENDPOINT => Attribute::OAuth2AuthorisationEndpoint,
637 ATTR_OAUTH2_CLIENT_ID => Attribute::OAuth2ClientId,
638 ATTR_OAUTH2_CLIENT_SECRET => Attribute::OAuth2ClientSecret,
639 ATTR_OAUTH2_CONSENT_SCOPE_MAP => Attribute::OAuth2ConsentScopeMap,
640 ATTR_OAUTH2_DEVICE_FLOW_ENABLE => Attribute::OAuth2DeviceFlowEnable,
641 ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE => Attribute::OAuth2JwtLegacyCryptoEnable,
642 ATTR_OAUTH2_PREFER_SHORT_USERNAME => Attribute::OAuth2PreferShortUsername,
643 ATTR_OAUTH2_REFRESH_TOKEN_EXPIRY => Attribute::OAuth2RefreshTokenExpiry,
644 ATTR_OAUTH2_REQUEST_SCOPES => Attribute::OAuth2RequestScopes,
645 ATTR_OAUTH2_RS_BASIC_SECRET => Attribute::OAuth2RsBasicSecret,
646 ATTR_OAUTH2_RS_CLAIM_MAP => Attribute::OAuth2RsClaimMap,
647 ATTR_OAUTH2_RS_IMPLICIT_SCOPES => Attribute::OAuth2RsImplicitScopes,
648 ATTR_OAUTH2_RS_NAME => Attribute::OAuth2RsName,
649 ATTR_OAUTH2_RS_ORIGIN => Attribute::OAuth2RsOrigin,
650 ATTR_OAUTH2_RS_ORIGIN_LANDING => Attribute::OAuth2RsOriginLanding,
651 ATTR_OAUTH2_RS_SCOPE_MAP => Attribute::OAuth2RsScopeMap,
652 ATTR_OAUTH2_RS_SUP_SCOPE_MAP => Attribute::OAuth2RsSupScopeMap,
653 ATTR_OAUTH2_RS_TOKEN_KEY => Attribute::OAuth2RsTokenKey,
654 ATTR_OAUTH2_SESSION => Attribute::OAuth2Session,
655 ATTR_OAUTH2_STRICT_REDIRECT_URI => Attribute::OAuth2StrictRedirectUri,
656 ATTR_OAUTH2_TOKEN_ENDPOINT => Attribute::OAuth2TokenEndpoint,
657 ATTR_OAUTH2_TOKEN_INTROSPECT_ENDPOINT => Attribute::OAuth2TokenIntrospectEndpoint,
658 ATTR_OAUTH2_ACCOUNT_CREDENTIAL_UUID => Attribute::OAuth2AccountCredentialUuid,
659 ATTR_OAUTH2_ACCOUNT_PROVIDER => Attribute::OAuth2AccountProvider,
660 ATTR_OAUTH2_ACCOUNT_UNIQUE_USER_ID => Attribute::OAuth2AccountUniqueUserId,
661 ATTR_OAUTH2_ACCOUNT_UNIQUE_USER_SUB => Attribute::OAuth2AccountUniqueUserSub,
662 ATTR_OAUTH2_CONSENT_PROMPT_ENABLE => Attribute::OAuth2ConsentPromptEnable,
663 ATTR_OBJECTCLASS => Attribute::ObjectClass,
664 ATTR_OTHER_NO_INDEX => Attribute::OtherNoIndex,
665 ATTR_PASSKEYS => Attribute::PassKeys,
666 ATTR_PASSWORD_IMPORT => Attribute::PasswordImport,
667 ATTR_PATCH_LEVEL => Attribute::PatchLevel,
668 ATTR_PHANTOM => Attribute::Phantom,
669 ATTR_PRIMARY_CREDENTIAL => Attribute::PrimaryCredential,
670 ATTR_PRIVATE_COOKIE_KEY => Attribute::PrivateCookieKey,
671 ATTR_PRIVILEGE_EXPIRY => Attribute::PrivilegeExpiry,
672 ATTR_PWD_CHANGED_TIME => Attribute::PasswordChangedTime,
673 ATTR_RADIUS_SECRET => Attribute::RadiusSecret,
674 ATTR_RECYCLEDDIRECTMEMBEROF => Attribute::RecycledDirectMemberOf,
675 ATTR_REFERS => Attribute::Refers,
676 ATTR_REPLICATED => Attribute::Replicated,
677 ATTR_RS256_PRIVATE_KEY_DER => Attribute::Rs256PrivateKeyDer,
678 ATTR_S256 => Attribute::S256,
679 ATTR_SCIM_SCHEMAS => Attribute::ScimSchemas,
680 ATTR_SEND_AFTER => Attribute::SendAfter,
681 ATTR_SENT_AT => Attribute::SentAt,
682 ATTR_SCOPE => Attribute::Scope,
683 ATTR_SOURCE_UUID => Attribute::SourceUuid,
684 ATTR_SPN => Attribute::Spn,
685 ATTR_LDAP_SSHPUBLICKEY => Attribute::LdapSshPublicKey,
686 ATTR_SUDOHOST => Attribute::SudoHost,
687 ATTR_SUPPLEMENTS => Attribute::Supplements,
688 ATTR_SYNC_ALLOWED => Attribute::SyncAllowed,
689 ATTR_SYNC_CLASS => Attribute::SyncClass,
690 ATTR_SYNC_COOKIE => Attribute::SyncCookie,
691 ATTR_SYNC_CREDENTIAL_PORTAL => Attribute::SyncCredentialPortal,
692 ATTR_SYNC_EXTERNAL_ID => Attribute::SyncExternalId,
693 ATTR_SYNC_PARENT_UUID => Attribute::SyncParentUuid,
694 ATTR_SYNC_TOKEN_SESSION => Attribute::SyncTokenSession,
695 ATTR_SYNC_YIELD_AUTHORITY => Attribute::SyncYieldAuthority,
696 ATTR_SYNTAX => Attribute::Syntax,
697 ATTR_SYSTEMEXCLUDES => Attribute::SystemExcludes,
698 ATTR_SYSTEMMAY => Attribute::SystemMay,
699 ATTR_SYSTEMMUST => Attribute::SystemMust,
700 ATTR_SYSTEMSUPPLEMENTS => Attribute::SystemSupplements,
701 ATTR_TERM => Attribute::Term,
702 ATTR_TOTP_IMPORT => Attribute::TotpImport,
703 ATTR_UID => Attribute::Uid,
704 ATTR_UIDNUMBER => Attribute::UidNumber,
705 ATTR_UNIQUE => Attribute::Unique,
706 ATTR_UNIX_PASSWORD => Attribute::UnixPassword,
707 ATTR_UNIX_PASSWORD_IMPORT => Attribute::UnixPasswordImport,
708 ATTR_USER_AUTH_TOKEN_SESSION => Attribute::UserAuthTokenSession,
709 ATTR_USERID => Attribute::UserId,
710 ATTR_USERPASSWORD => Attribute::UserPassword,
711 ATTR_UUID => Attribute::Uuid,
712 ATTR_VERSION => Attribute::Version,
713 ATTR_WEBAUTHN_ATTESTATION_CA_LIST => Attribute::WebauthnAttestationCaList,
714
715 #[cfg(any(debug_assertions, test, feature = "test"))]
716 TEST_ATTR_NON_EXIST => Attribute::NonExist,
717 #[cfg(any(debug_assertions, test, feature = "test"))]
718 TEST_ATTR_TEST_ATTR => Attribute::TestAttr,
719
720 #[cfg(test)]
721 TEST_ATTR_TEST_ATTR_A => Attribute::TestAttrA,
722 #[cfg(test)]
723 TEST_ATTR_TEST_ATTR_B => Attribute::TestAttrB,
724 #[cfg(test)]
725 TEST_ATTR_TEST_ATTR_C => Attribute::TestAttrC,
726 #[cfg(test)]
727 TEST_ATTR_TEST_ATTR_D => Attribute::TestAttrD,
728
729 #[cfg(any(debug_assertions, test, feature = "test"))]
730 TEST_ATTR_EXTRA => Attribute::Extra,
731 #[cfg(any(debug_assertions, test, feature = "test"))]
732 TEST_ATTR_NUMBER => Attribute::TestNumber,
733 #[cfg(any(debug_assertions, test, feature = "test"))]
734 TEST_ATTR_NOTALLOWED => Attribute::TestNotAllowed,
735
736 #[cfg(not(test))]
737 _ => Attribute::Custom(AttrString::from(value)),
738 #[allow(clippy::unreachable)]
740 #[cfg(test)]
741 _ => {
742 unreachable!(
743 "Check that you've implemented the Attribute conversion for {:?}",
744 value
745 );
746 }
747 }
748 }
749}
750
751impl fmt::Display for Attribute {
752 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753 write!(f, "{}", self.as_str())
754 }
755}
756
757impl From<Attribute> for String {
758 fn from(attr: Attribute) -> String {
759 attr.to_string()
760 }
761}
762
763#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, ToSchema)]
766#[serde(rename_all = "lowercase", try_from = "&str", into = "AttrString")]
767pub enum SubAttribute {
768 Primary,
770 Type,
772 Value,
774
775 #[cfg(not(test))]
776 #[schema(value_type = String)]
777 Custom(AttrString),
778}
779
780impl fmt::Display for SubAttribute {
781 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
782 write!(f, "{}", self.as_str())
783 }
784}
785
786impl From<SubAttribute> for AttrString {
787 fn from(val: SubAttribute) -> Self {
788 AttrString::from(val.as_str())
789 }
790}
791
792impl From<&str> for SubAttribute {
793 fn from(value: &str) -> Self {
794 Self::inner_from_str(value)
795 }
796}
797
798impl FromStr for SubAttribute {
799 type Err = Infallible;
800
801 fn from_str(value: &str) -> Result<Self, Self::Err> {
802 Ok(Self::inner_from_str(value))
803 }
804}
805
806impl SubAttribute {
807 pub fn as_str(&self) -> &str {
808 match self {
809 SubAttribute::Primary => SUB_ATTR_PRIMARY,
810 SubAttribute::Type => SUB_ATTR_TYPE,
811 SubAttribute::Value => SUB_ATTR_VALUE,
812 #[cfg(not(test))]
813 SubAttribute::Custom(s) => s,
814 }
815 }
816
817 #[allow(clippy::should_implement_trait)]
819 fn inner_from_str(value: &str) -> Self {
820 match value.to_lowercase().as_str() {
823 SUB_ATTR_PRIMARY => SubAttribute::Primary,
824 SUB_ATTR_TYPE => SubAttribute::Type,
825 SUB_ATTR_VALUE => SubAttribute::Value,
826
827 #[cfg(not(test))]
828 _ => SubAttribute::Custom(AttrString::from(value)),
829
830 #[allow(clippy::unreachable)]
832 #[cfg(test)]
833 _ => {
834 unreachable!(
835 "Check that you've implemented the SubAttribute conversion for {:?}",
836 value
837 );
838 }
839 }
840 }
841}
842
843#[cfg(test)]
844mod test {
845 use super::Attribute;
846
847 #[test]
848 fn test_valueattribute_from_str() {
849 assert_eq!(Attribute::Uuid, Attribute::from("UUID"));
850 assert_eq!(Attribute::Uuid, Attribute::from("UuiD"));
851 assert_eq!(Attribute::Uuid, Attribute::from("uuid"));
852 }
853
854 #[test]
855 fn test_valueattribute_as_str() {
856 assert_eq!(Attribute::Class.as_str(), "class");
857 assert_eq!(Attribute::Class.to_string(), "class".to_string());
858 }
859
860 #[test]
861 fn test_valueattribute_round_trip() {
863 use enum_iterator::all;
864 let the_list = all::<Attribute>().collect::<Vec<_>>();
865 for attr in the_list {
866 let attr2 = Attribute::from(attr.as_str());
867 assert!(
868 attr == attr2,
869 "Round-trip failed for {attr} <=> {attr2} check you've implemented a from and to string"
870 );
871 }
872 }
873}