@@ -131,13 +131,37 @@ impl ExpiringKey {
131
131
}
132
132
}
133
133
134
- /// A randomly generated token used for authentication.
134
+ /// A token used for authentication.
135
135
///
136
- /// It contains lower and uppercase letters and numbers.
137
- /// It's a 32-char string.
136
+ /// - It contains only ascii alphanumeric chars: lower and uppercase letters and
137
+ /// numbers.
138
+ /// - It's a 32-char string.
138
139
#[ derive( Serialize , Deserialize , Debug , Eq , PartialEq , Clone , Display , Hash ) ]
139
140
pub struct Key ( String ) ;
140
141
142
+ impl Key {
143
+ /// # Errors
144
+ ///
145
+ /// Will return an error is the string represents an invalid key.
146
+ /// Valid keys can only contain 32 chars including 0-9, a-z and A-Z.
147
+ pub fn new ( value : & str ) -> Result < Self , ParseKeyError > {
148
+ if value. len ( ) != AUTH_KEY_LENGTH {
149
+ return Err ( ParseKeyError ) ;
150
+ }
151
+
152
+ if !value. chars ( ) . all ( |c| c. is_ascii_alphanumeric ( ) ) {
153
+ return Err ( ParseKeyError ) ;
154
+ }
155
+
156
+ Ok ( Self ( value. to_owned ( ) ) )
157
+ }
158
+
159
+ #[ must_use]
160
+ pub fn value ( & self ) -> & str {
161
+ & self . 0
162
+ }
163
+ }
164
+
141
165
/// Error returned when a key cannot be parsed from a string.
142
166
///
143
167
/// ```rust,no_run
@@ -159,10 +183,7 @@ impl FromStr for Key {
159
183
type Err = ParseKeyError ;
160
184
161
185
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
162
- if s. len ( ) != AUTH_KEY_LENGTH {
163
- return Err ( ParseKeyError ) ;
164
- }
165
-
186
+ Key :: new ( s) ?;
166
187
Ok ( Self ( s. to_string ( ) ) )
167
188
}
168
189
}
@@ -209,6 +230,22 @@ mod tests {
209
230
assert ! ( key. is_ok( ) ) ;
210
231
assert_eq ! ( key. unwrap( ) . to_string( ) , key_string) ;
211
232
}
233
+
234
+ #[ test]
235
+ fn length_should_be_32 ( ) {
236
+ let key = Key :: new ( "" ) ;
237
+ assert ! ( key. is_err( ) ) ;
238
+
239
+ let string_longer_than_32 = "012345678901234567890123456789012" ; // DevSkim: ignore DS173237
240
+ let key = Key :: new ( string_longer_than_32) ;
241
+ assert ! ( key. is_err( ) ) ;
242
+ }
243
+
244
+ #[ test]
245
+ fn should_only_include_alphanumeric_chars ( ) {
246
+ let key = Key :: new ( "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" ) ;
247
+ assert ! ( key. is_err( ) ) ;
248
+ }
212
249
}
213
250
214
251
mod expiring_auth_key {
0 commit comments