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