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