@@ -91,7 +91,7 @@ secure_token_kind! {
91
91
///
92
92
/// NEVER CHANGE THE PREFIX OF EXISTING TOKEN TYPES!!! Doing so will implicitly revoke all the
93
93
/// tokens of that kind, distrupting production users.
94
- #[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
94
+ #[ derive( Debug , Copy , Clone , Eq , PartialEq , Hash ) ]
95
95
pub ( crate ) enum SecureTokenKind {
96
96
API => "cio" , // Crates.IO
97
97
}
@@ -109,6 +109,7 @@ impl SecureTokenKind {
109
109
#[ cfg( test) ]
110
110
mod tests {
111
111
use super :: * ;
112
+ use std:: collections:: HashSet ;
112
113
113
114
#[ test]
114
115
fn test_generated_and_parse ( ) {
@@ -130,4 +131,40 @@ mod tests {
130
131
fn test_parse_no_kind ( ) {
131
132
assert ! ( SecureToken :: parse( SecureTokenKind :: API , "nokind" ) . is_none( ) ) ;
132
133
}
134
+
135
+ #[ test]
136
+ fn test_persistent_prefixes ( ) {
137
+ // Changing prefixes will implicitly revoke all the tokens of that kind, disrupting users.
138
+ // This test serves as a reminder for future maintainers not to change the prefixes, and
139
+ // to ensure all the variants are tested by this test.
140
+ let mut remaining: HashSet < _ > = SecureTokenKind :: VARIANTS . iter ( ) . copied ( ) . collect ( ) ;
141
+ let mut ensure = |kind : SecureTokenKind , prefix| {
142
+ assert_eq ! ( kind. prefix( ) , prefix) ;
143
+ remaining. remove ( & kind) ;
144
+ } ;
145
+
146
+ ensure ( SecureTokenKind :: API , "cio" ) ;
147
+
148
+ assert ! (
149
+ remaining. is_empty( ) ,
150
+ "not all variants have a test to check the prefix"
151
+ ) ;
152
+ }
153
+
154
+ #[ test]
155
+ fn test_conflicting_prefixes ( ) {
156
+ // This sanity check prevents multiple tokens from starting with the same prefix, which
157
+ // would mess up the token kind detection. If this test fails after adding another variant
158
+ // do not change the test, choose another prefix instead.
159
+ for variant in SecureTokenKind :: VARIANTS {
160
+ for other in SecureTokenKind :: VARIANTS {
161
+ if variant == other {
162
+ continue ;
163
+ }
164
+ if variant. prefix ( ) . starts_with ( other. prefix ( ) ) {
165
+ panic ! ( "variants {:?} and {:?} share a prefix" , variant, other) ;
166
+ }
167
+ }
168
+ }
169
+ }
133
170
}
0 commit comments