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