@@ -263,13 +263,15 @@ func TestAuthOnlyEndpoint(t *testing.T) {
263
263
264
264
for _ , tc := range testCases {
265
265
t .Run (tc .name , func (t * testing.T ) {
266
+ providerURL , _ := url .Parse ("http://localhost/" )
267
+ tp := providers .NewTestProvider (providerURL , "" )
268
+ tp .RefreshSessionFunc = func (* sessions.SessionState , []string ) (bool , error ) { return true , nil }
269
+ tp .ValidateSessionFunc = func (* sessions.SessionState , []string ) bool { return true }
270
+
266
271
proxy , close := testNewOAuthProxy (t ,
267
272
setSessionStore (tc .sessionStore ),
268
273
setValidator (func (_ string ) bool { return tc .validEmail }),
269
- SetProvider (& providers.TestProvider {
270
- RefreshSessionFunc : func (* sessions.SessionState , []string ) (bool , error ) { return true , nil },
271
- ValidateSessionFunc : func (* sessions.SessionState , []string ) bool { return true },
272
- }),
274
+ SetProvider (tp ),
273
275
)
274
276
defer close ()
275
277
@@ -571,16 +573,31 @@ func TestAuthenticate(t *testing.T) {
571
573
CookieExpectation : NewCookie ,
572
574
ValidateSessionFunc : func (s * sessions.SessionState , g []string ) bool { return true },
573
575
},
576
+ {
577
+ Name : "wrong identity provider, user OK, do not authenticate" ,
578
+ SessionStore : & sessions.MockSessionStore {
579
+ Session : & sessions.SessionState {
580
+ ProviderSlug : "example" ,
581
+
582
+ AccessToken : "my_access_token" ,
583
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
584
+ RefreshDeadline : time .Now ().Add (time .Duration (1 ) * time .Hour ),
585
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
586
+ },
587
+ },
588
+ ExpectedErr : ErrWrongIdentityProvider ,
589
+ CookieExpectation : ClearCookie ,
590
+ },
574
591
}
575
592
for _ , tc := range testCases {
576
593
t .Run (tc .Name , func (t * testing.T ) {
577
- provider := & providers. TestProvider {
578
- RefreshSessionFunc : tc . RefreshSessionFunc ,
579
- ValidateSessionFunc : tc .ValidateSessionFunc ,
580
- }
594
+ providerURL , _ := url . Parse ( "http://localhost/" )
595
+ tp := providers . NewTestProvider ( providerURL , "" )
596
+ tp . RefreshSessionFunc = tc .RefreshSessionFunc
597
+ tp . ValidateSessionFunc = tc . ValidateSessionFunc
581
598
582
599
proxy , close := testNewOAuthProxy (t ,
583
- SetProvider (provider ),
600
+ SetProvider (tp ),
584
601
setSessionStore (tc .SessionStore ),
585
602
)
586
603
defer close ()
@@ -608,6 +625,194 @@ func TestAuthenticate(t *testing.T) {
608
625
}
609
626
}
610
627
628
+ func TestAuthenticationUXFlows (t * testing.T ) {
629
+ var (
630
+ ErrRefreshFailed = errors .New ("refresh failed" )
631
+ LoadCookieFailed = errors .New ("load cookie fail" )
632
+ SaveCookieFailed = errors .New ("save cookie fail" )
633
+ )
634
+ testCases := []struct {
635
+ Name string
636
+
637
+ SessionStore * sessions.MockSessionStore
638
+ RefreshSessionFunc func (* sessions.SessionState , []string ) (bool , error )
639
+ ValidateSessionFunc func (* sessions.SessionState , []string ) bool
640
+
641
+ ExpectStatusCode int
642
+ }{
643
+ {
644
+ Name : "missing deadlines, redirect to sign-in" ,
645
+ SessionStore : & sessions.MockSessionStore {
646
+ Session : & sessions.SessionState {
647
+
648
+ AccessToken : "my_access_token" ,
649
+ },
650
+ },
651
+ ExpectStatusCode : http .StatusFound ,
652
+ },
653
+ {
654
+ Name : "session unmarshaling fails, show error" ,
655
+ SessionStore : & sessions.MockSessionStore {
656
+ Session : & sessions.SessionState {},
657
+ LoadError : LoadCookieFailed ,
658
+ },
659
+ ExpectStatusCode : http .StatusInternalServerError ,
660
+ },
661
+ {
662
+ Name : "authenticate successfully, expect ok" ,
663
+ SessionStore : & sessions.MockSessionStore {
664
+ Session : & sessions.SessionState {
665
+
666
+ AccessToken : "my_access_token" ,
667
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
668
+ RefreshDeadline : time .Now ().Add (time .Duration (1 ) * time .Hour ),
669
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
670
+ },
671
+ },
672
+ ExpectStatusCode : http .StatusOK ,
673
+ },
674
+ {
675
+ Name : "lifetime expired, redirect to sign-in" ,
676
+ SessionStore : & sessions.MockSessionStore {
677
+ Session : & sessions.SessionState {
678
+
679
+ AccessToken : "my_access_token" ,
680
+ LifetimeDeadline : time .Now ().Add (time .Duration (- 24 ) * time .Hour ),
681
+ RefreshDeadline : time .Now ().Add (time .Duration (1 ) * time .Hour ),
682
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
683
+ },
684
+ },
685
+ ExpectStatusCode : http .StatusFound ,
686
+ },
687
+ {
688
+ Name : "refresh expired, refresh fails, show error" ,
689
+ SessionStore : & sessions.MockSessionStore {
690
+ Session : & sessions.SessionState {
691
+
692
+ AccessToken : "my_access_token" ,
693
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
694
+ RefreshDeadline : time .Now ().Add (time .Duration (- 1 ) * time .Hour ),
695
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
696
+ },
697
+ },
698
+ RefreshSessionFunc : func (s * sessions.SessionState , g []string ) (bool , error ) { return false , ErrRefreshFailed },
699
+ ExpectStatusCode : http .StatusInternalServerError ,
700
+ },
701
+ {
702
+ Name : "refresh expired, user not OK, deny" ,
703
+ SessionStore : & sessions.MockSessionStore {
704
+ Session : & sessions.SessionState {
705
+
706
+ AccessToken : "my_access_token" ,
707
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
708
+ RefreshDeadline : time .Now ().Add (time .Duration (- 1 ) * time .Hour ),
709
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
710
+ },
711
+ },
712
+ RefreshSessionFunc : func (s * sessions.SessionState , g []string ) (bool , error ) { return false , nil },
713
+ ExpectStatusCode : http .StatusForbidden ,
714
+ },
715
+ {
716
+ Name : "refresh expired, user OK, expect ok" ,
717
+ SessionStore : & sessions.MockSessionStore {
718
+ Session : & sessions.SessionState {
719
+
720
+ AccessToken : "my_access_token" ,
721
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
722
+ RefreshDeadline : time .Now ().Add (time .Duration (- 1 ) * time .Hour ),
723
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
724
+ },
725
+ },
726
+ RefreshSessionFunc : func (s * sessions.SessionState , g []string ) (bool , error ) { return true , nil },
727
+ ExpectStatusCode : http .StatusOK ,
728
+ },
729
+ {
730
+ Name : "refresh expired, refresh and user OK, error saving session, show error" ,
731
+ SessionStore : & sessions.MockSessionStore {
732
+ Session : & sessions.SessionState {
733
+
734
+ AccessToken : "my_access_token" ,
735
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
736
+ RefreshDeadline : time .Now ().Add (time .Duration (- 1 ) * time .Hour ),
737
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
738
+ },
739
+ SaveError : SaveCookieFailed ,
740
+ },
741
+ RefreshSessionFunc : func (s * sessions.SessionState , g []string ) (bool , error ) { return true , nil },
742
+ ExpectStatusCode : http .StatusInternalServerError ,
743
+ },
744
+ {
745
+ Name : "validation expired, user not OK, deny" ,
746
+ SessionStore : & sessions.MockSessionStore {
747
+ Session : & sessions.SessionState {
748
+
749
+ AccessToken : "my_access_token" ,
750
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
751
+ RefreshDeadline : time .Now ().Add (time .Duration (1 ) * time .Hour ),
752
+ ValidDeadline : time .Now ().Add (time .Duration (- 1 ) * time .Minute ),
753
+ },
754
+ },
755
+ ValidateSessionFunc : func (s * sessions.SessionState , g []string ) bool { return false },
756
+ ExpectStatusCode : http .StatusForbidden ,
757
+ },
758
+ {
759
+ Name : "validation expired, user OK, expect ok" ,
760
+ SessionStore : & sessions.MockSessionStore {
761
+ Session : & sessions.SessionState {
762
+
763
+ AccessToken : "my_access_token" ,
764
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
765
+ RefreshDeadline : time .Now ().Add (time .Duration (1 ) * time .Hour ),
766
+ ValidDeadline : time .Now ().Add (time .Duration (- 1 ) * time .Minute ),
767
+ },
768
+ },
769
+ ValidateSessionFunc : func (s * sessions.SessionState , g []string ) bool { return true },
770
+ ExpectStatusCode : http .StatusOK ,
771
+ },
772
+ {
773
+ Name : "wrong identity provider, redirect to sign-in" ,
774
+ SessionStore : & sessions.MockSessionStore {
775
+ Session : & sessions.SessionState {
776
+ ProviderSlug : "example" ,
777
+
778
+ AccessToken : "my_access_token" ,
779
+ LifetimeDeadline : time .Now ().Add (time .Duration (24 ) * time .Hour ),
780
+ RefreshDeadline : time .Now ().Add (time .Duration (1 ) * time .Hour ),
781
+ ValidDeadline : time .Now ().Add (time .Duration (1 ) * time .Minute ),
782
+ },
783
+ },
784
+ ExpectStatusCode : http .StatusFound ,
785
+ },
786
+ }
787
+ for _ , tc := range testCases {
788
+ t .Run (tc .Name , func (t * testing.T ) {
789
+ providerURL , _ := url .Parse ("http://localhost/" )
790
+ tp := providers .NewTestProvider (providerURL , "" )
791
+ tp .RefreshSessionFunc = tc .RefreshSessionFunc
792
+ tp .ValidateSessionFunc = tc .ValidateSessionFunc
793
+
794
+ proxy , close := testNewOAuthProxy (t ,
795
+ SetProvider (tp ),
796
+ setSessionStore (tc .SessionStore ),
797
+ )
798
+ defer close ()
799
+
800
+ req := httptest .NewRequest ("GET" , "https://localhost" , nil )
801
+ rw := httptest .NewRecorder ()
802
+
803
+ proxy .Proxy (rw , req )
804
+
805
+ res := rw .Result ()
806
+
807
+ if tc .ExpectStatusCode != res .StatusCode {
808
+ t .Errorf ("have: %v" , res .StatusCode )
809
+ t .Errorf ("want: %v" , tc .ExpectStatusCode )
810
+ t .Fatalf ("expected status codes to be equal" )
811
+ }
812
+ })
813
+ }
814
+ }
815
+
611
816
func TestProxyXHRErrorHandling (t * testing.T ) {
612
817
testCases := []struct {
613
818
Name string
0 commit comments