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