@@ -3,6 +3,8 @@ package proto
33import (
44 "crypto/sha256"
55 "encoding/hex"
6+ "fmt"
7+ "strings"
68 "testing"
79
810 "github.com/stretchr/testify/assert"
@@ -268,179 +270,6 @@ func TestAuthID_Encode(t *testing.T) {
268270 }
269271}
270272
271- func TestAuthID_FromString (t * testing.T ) {
272- tests := []struct {
273- name string
274- input string
275- expected AuthID
276- expectedError bool
277- errorContains string
278- }{
279- {
280- name : "valid auth ID string with all fields" ,
281- input : "@123:test/OTP/Email/user@example.com" ,
282- expected : AuthID {
283- Scope : "@123:test" ,
284- AuthMode : AuthMode_OTP ,
285- IdentityType : IdentityType_Email ,
286- Verifier : "user@example.com" ,
287- },
288- expectedError : false ,
289- },
290- {
291- name : "valid auth ID string with minimal scope" ,
292- input : "@456/IDToken/OIDC/sub123" ,
293- expected : AuthID {
294- Scope : "@456" ,
295- AuthMode : AuthMode_IDToken ,
296- IdentityType : IdentityType_OIDC ,
297- Verifier : "sub123" ,
298- },
299- expectedError : false ,
300- },
301- {
302- name : "valid auth ID string with special characters" ,
303- input : "@789:app/AuthCode/Email/user+test@example-domain.co.uk" ,
304- expected : AuthID {
305- Scope : "@789:app" ,
306- AuthMode : AuthMode_AuthCode ,
307- IdentityType : IdentityType_Email ,
308- Verifier : "user+test@example-domain.co.uk" ,
309- },
310- expectedError : false ,
311- },
312- {
313- name : "valid auth ID string with unicode" ,
314- input : "@999:unicode/AccessToken/Email/用户@测试.中国" ,
315- expected : AuthID {
316- Scope : "@999:unicode" ,
317- AuthMode : AuthMode_AccessToken ,
318- IdentityType : IdentityType_Email ,
319- Verifier : "用户@测试.中国" ,
320- },
321- expectedError : false ,
322- },
323- {
324- name : "valid auth ID string with AuthCodePKCE" ,
325- input : "@100:pkce/AuthCodePKCE/OIDC/oauth-client-id" ,
326- expected : AuthID {
327- Scope : "@100:pkce" ,
328- AuthMode : AuthMode_AuthCodePKCE ,
329- IdentityType : IdentityType_OIDC ,
330- Verifier : "oauth-client-id" ,
331- },
332- expectedError : false ,
333- },
334- {
335- name : "invalid format - too few parts" ,
336- input : "@123/OTP/Email" ,
337- expectedError : true ,
338- errorContains : "invalid auth ID format:" ,
339- },
340- {
341- name : "invalid format - too many parts" ,
342- input : "@123/OTP/Email/user@example.com/extra" ,
343- expectedError : true ,
344- errorContains : "invalid verifier:" ,
345- },
346- {
347- name : "invalid format - empty string" ,
348- input : "" ,
349- expectedError : true ,
350- errorContains : "invalid auth ID format:" ,
351- },
352- {
353- name : "invalid format - no separators" ,
354- input : "invalidauthid" ,
355- expectedError : true ,
356- errorContains : "invalid auth ID format:" ,
357- },
358- {
359- name : "invalid format - only one separator" ,
360- input : "@123/OTP" ,
361- expectedError : true ,
362- errorContains : "invalid auth ID format:" ,
363- },
364- {
365- name : "invalid format - only two separators" ,
366- input : "@123/OTP/Email" ,
367- expectedError : true ,
368- errorContains : "invalid auth ID format:" ,
369- },
370- {
371- name : "invalid - empty scope" ,
372- input : "/OTP/Email/user@example.com" ,
373- expectedError : true ,
374- errorContains : "invalid scope:" ,
375- },
376- {
377- name : "invalid - scope contains slash" ,
378- input : "@123/test/OTP/Email/user@example.com" ,
379- expectedError : true ,
380- errorContains : "invalid verifier:" ,
381- },
382- {
383- name : "invalid - empty auth mode" ,
384- input : "@123:test//Email/user@example.com" ,
385- expectedError : true ,
386- errorContains : "invalid auth mode:" ,
387- },
388- {
389- name : "invalid - auth mode contains slash" ,
390- input : "@123:test/OTP/Invalid/Email/user@example.com" ,
391- expectedError : true ,
392- errorContains : "invalid verifier:" ,
393- },
394- {
395- name : "invalid - empty identity type" ,
396- input : "@123:test/OTP//user@example.com" ,
397- expectedError : true ,
398- errorContains : "invalid identity type:" ,
399- },
400- {
401- name : "invalid - identity type contains slash" ,
402- input : "@123:test/OTP/Email/Invalid/user@example.com" ,
403- expectedError : true ,
404- errorContains : "invalid verifier:" ,
405- },
406- {
407- name : "invalid - empty verifier" ,
408- input : "@123:test/OTP/Email/" ,
409- expectedError : true ,
410- errorContains : "invalid verifier:" ,
411- },
412- {
413- name : "invalid - verifier contains slash" ,
414- input : "@123:test/OTP/Email/user/example.com" ,
415- expectedError : true ,
416- errorContains : "invalid verifier:" ,
417- },
418- {
419- name : "invalid - verifier too long" ,
420- input : "@123:test/OTP/Email/" + string (make ([]byte , 251 )),
421- expectedError : true ,
422- errorContains : "verifier is too long: 251" ,
423- },
424- }
425-
426- for _ , tt := range tests {
427- t .Run (tt .name , func (t * testing.T ) {
428- var authID AuthID
429- err := authID .FromString (tt .input )
430-
431- if tt .expectedError {
432- require .Error (t , err )
433- if tt .errorContains != "" {
434- assert .Contains (t , err .Error (), tt .errorContains )
435- }
436- } else {
437- require .NoError (t , err )
438- assert .Equal (t , tt .expected , authID )
439- }
440- })
441- }
442- }
443-
444273func TestAuthID_Hash (t * testing.T ) {
445274 tests := []struct {
446275 name string
@@ -581,8 +410,7 @@ func TestAuthID_EncodeFromString_Roundtrip(t *testing.T) {
581410 require .NoError (t , err )
582411
583412 // Parse it back
584- var parsed AuthID
585- err = parsed .FromString (encoded )
413+ parsed , err := parseAuthID (encoded )
586414 require .NoError (t , err )
587415
588416 // Should be identical
@@ -746,8 +574,7 @@ func TestAuthID_AllAuthModes(t *testing.T) {
746574 encoded , err := authID .Encode ()
747575 require .NoError (t , err )
748576
749- var parsed AuthID
750- err = parsed .FromString (encoded )
577+ parsed , err := parseAuthID (encoded )
751578 require .NoError (t , err )
752579 assert .Equal (t , authID , parsed )
753580 })
@@ -775,8 +602,7 @@ func TestAuthID_AllIdentityTypes(t *testing.T) {
775602 encoded , err := authID .Encode ()
776603 require .NoError (t , err )
777604
778- var parsed AuthID
779- err = parsed .FromString (encoded )
605+ parsed , err := parseAuthID (encoded )
780606 require .NoError (t , err )
781607 assert .Equal (t , authID , parsed )
782608 })
@@ -812,16 +638,6 @@ func BenchmarkAuthID_Encode(b *testing.B) {
812638 }
813639}
814640
815- func BenchmarkAuthID_FromString (b * testing.B ) {
816- authIDStr := "@123:test/OTP/Email/user@example.com"
817-
818- b .ResetTimer ()
819- for i := 0 ; i < b .N ; i ++ {
820- var authID AuthID
821- _ = authID .FromString (authIDStr )
822- }
823- }
824-
825641func BenchmarkAuthID_Hash (b * testing.B ) {
826642 authID := AuthID {
827643 Scope : "@123:test" ,
@@ -836,18 +652,18 @@ func BenchmarkAuthID_Hash(b *testing.B) {
836652 }
837653}
838654
839- func BenchmarkAuthID_EncodeFromString_Roundtrip (b * testing.B ) {
840- authID := AuthID {
841- Scope : "@123:test" ,
842- AuthMode : AuthMode_OTP ,
843- IdentityType : IdentityType_Email ,
844- Verifier : "user@example.com" ,
655+ func parseAuthID (s string ) (AuthID , error ) {
656+ parts := strings .SplitN (s , "/" , 4 )
657+ if len (parts ) != 4 {
658+ return AuthID {}, fmt .Errorf ("invalid auth ID format: %s" , s )
845659 }
846660
847- b . ResetTimer ()
848- for i := 0 ; i < b . N ; i ++ {
849- encoded , _ := authID . Encode ()
850- var parsed AuthID
851- _ = parsed . FromString ( encoded )
661+ authID := AuthID {
662+ Scope : Scope ( parts [ 0 ]),
663+ AuthMode : AuthMode ( parts [ 1 ]),
664+ IdentityType : IdentityType ( parts [ 2 ]),
665+ Verifier : parts [ 3 ],
852666 }
667+
668+ return authID , nil
853669}
0 commit comments