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