@@ -526,8 +526,20 @@ impl<'de> Deserialize<'de> for Capability {
526526 {
527527 let input = String :: deserialize ( deserializer) ?;
528528 let upper = input. to_uppercase ( ) ;
529- let stripped = upper. strip_prefix ( "CAP_" ) . unwrap_or ( & upper) ;
530- match stripped {
529+
530+ // Extract the capability name from various input formats.
531+ //
532+ // This function strips all "CAP_" prefixes to normalize capability names.
533+ // This ensures correct adaptation regardless of whether users specify
534+ // CAP_XXX or XXX directly at the upper layer(Specially k8s), making the
535+ // API more flexible and user-friendly.
536+ // Examples: "CAP_SYS_ADMIN", "SYS_ADMIN"
537+ //
538+ let mut clean_cap = upper. as_str ( ) ;
539+ while let Some ( stripped) = clean_cap. strip_prefix ( "CAP_" ) {
540+ clean_cap = stripped;
541+ }
542+ match clean_cap {
531543 "AUDIT_CONTROL" => Ok ( Self :: AuditControl ) ,
532544 "AUDIT_READ" => Ok ( Self :: AuditRead ) ,
533545 "AUDIT_WRITE" => Ok ( Self :: AuditWrite ) ,
@@ -668,4 +680,13 @@ mod tests {
668680 let cap: Capability = serde_json:: from_str ( serialized) . unwrap ( ) ;
669681 assert_eq ! ( cap, Capability :: SysAdmin ) ;
670682 }
683+
684+ #[ test]
685+ fn deserialize_one_more_cap_prefix ( ) -> Result < ( ) > {
686+ for case in & [ "SYS_ADMIN" , "CAP_CAP_SYS_ADMIN" , "cap_CAP_cap_SYS_ADMIN" ] {
687+ let res: Capability = serde_json:: from_str ( & format ! ( "\" {case}\" " ) ) ?;
688+ assert_eq ! ( Capability :: SysAdmin , res) ;
689+ }
690+ Ok ( ( ) )
691+ }
671692}
0 commit comments