@@ -14,23 +14,25 @@ class MockHttpRequest : HttpRequestBase
14
14
{
15
15
public MockHttpRequest ( )
16
16
{
17
- this . QueryStringValue = new NameValueCollection ( ) ;
17
+ QueryStringValue = new NameValueCollection ( ) ;
18
+ HeadersValue = new NameValueCollection ( ) ;
18
19
}
20
+
19
21
public HttpCookieCollection CookiesValue { get ; set ; }
20
22
public string UserAgentValue { get ; set ; }
21
23
public NameValueCollection QueryStringValue { get ; set ; }
22
24
public Uri UrlValue { get ; set ; }
23
- public override string UserAgent
24
- {
25
- get
26
- {
27
- return UserAgentValue ;
28
- }
29
- }
25
+ public string UserHostAddressValue { get ; set ; }
26
+ public NameValueCollection HeadersValue { get ; set ; }
27
+
28
+ public override string UserAgent => UserAgentValue ;
30
29
public override HttpCookieCollection Cookies => this . CookiesValue ;
31
30
public override NameValueCollection QueryString => QueryStringValue ;
32
31
public override Uri Url => UrlValue ;
32
+ public override string UserHostAddress => UserHostAddressValue ;
33
+ public override NameValueCollection Headers => HeadersValue ;
33
34
}
35
+
34
36
class MockHttpResponse : HttpResponseBase
35
37
{
36
38
public HttpCookieCollection CookiesValue { get ; set ; }
@@ -62,7 +64,7 @@ class UserInQueueServiceMock : IUserInQueueService
62
64
public List < List < string > > validateQueueRequestCalls = new List < List < string > > ( ) ;
63
65
public List < List < string > > extendQueueCookieCalls = new List < List < string > > ( ) ;
64
66
public List < List < string > > cancelRequestCalls = new List < List < string > > ( ) ;
65
-
67
+
66
68
public RequestValidationResult ValidateQueueRequest ( string targetUrl , string queueitToken , QueueEventConfig config , string customerId , string secretKey )
67
69
{
68
70
List < string > args = new List < string > ( ) ;
@@ -108,15 +110,37 @@ public RequestValidationResult ValidateCancelRequest(string targetUrl, CancelEve
108
110
}
109
111
}
110
112
113
+ private void AssertRequestCookieContent ( string [ ] cookieValues , params string [ ] expectedValues )
114
+ {
115
+ Assert . True ( cookieValues . Count ( v => v . StartsWith ( "ServerUtcTime=" ) ) == 1 ) ;
116
+ Assert . True ( cookieValues . Count ( v => v . StartsWith ( "RequestIP=" ) ) == 1 ) ;
117
+ Assert . True ( cookieValues . Count ( v => v . StartsWith ( "RequestHttpHeader_Via=" ) ) == 1 ) ;
118
+ Assert . True ( cookieValues . Count ( v => v . StartsWith ( "RequestHttpHeader_Forwarded=" ) ) == 1 ) ;
119
+ Assert . True ( cookieValues . Count ( v => v . StartsWith ( "RequestHttpHeader_XForwardedFor=" ) ) == 1 ) ;
120
+ Assert . True ( cookieValues . Count ( v => v . StartsWith ( "RequestHttpHeader_XForwardedHost=" ) ) == 1 ) ;
121
+ Assert . True ( cookieValues . Count ( v => v . StartsWith ( "RequestHttpHeader_XForwardedProto=" ) ) == 1 ) ;
122
+
123
+ var utcTimeInCookie = cookieValues . FirstOrDefault ( v => v . StartsWith ( "ServerUtcTime" ) ) . Split ( '=' ) [ 1 ] ;
124
+ Assert . True ( string . Compare ( expectedValues [ 0 ] , utcTimeInCookie ) <= 0 ) ;
125
+ Assert . True ( string . Compare ( DateTime . UtcNow . ToString ( "o" ) , utcTimeInCookie ) >= 0 ) ;
126
+
127
+ Assert . True ( cookieValues . Any ( v => v == $ "RequestIP={ expectedValues [ 1 ] } ") ) ;
128
+ Assert . True ( cookieValues . Any ( v => v == $ "RequestHttpHeader_Via={ expectedValues [ 2 ] } ") ) ;
129
+ Assert . True ( cookieValues . Any ( v => v == $ "RequestHttpHeader_Forwarded={ expectedValues [ 3 ] } ") ) ;
130
+ Assert . True ( cookieValues . Any ( v => v == $ "RequestHttpHeader_XForwardedFor={ expectedValues [ 4 ] } ") ) ;
131
+ Assert . True ( cookieValues . Any ( v => v == $ "RequestHttpHeader_XForwardedHost={ expectedValues [ 5 ] } ") ) ;
132
+ Assert . True ( cookieValues . Any ( v => v == $ "RequestHttpHeader_XForwardedProto={ expectedValues [ 6 ] } ") ) ;
133
+ }
134
+
111
135
[ Fact ]
112
136
public void CancelRequestByLocalConfig_Test ( )
113
137
{
114
138
// Arrange
115
139
UserInQueueServiceMock mock = new UserInQueueServiceMock ( ) ;
116
140
KnownUser . _UserInQueueService = ( mock ) ;
117
- var cancelEventConfig = new CancelEventConfig ( ) { CookieDomain = "cookiedomain" , EventId = "eventid" , QueueDomain = "queuedomain" , Version = 1 } ;
141
+ var cancelEventConfig = new CancelEventConfig ( ) { CookieDomain = "cookiedomain" , EventId = "eventid" , QueueDomain = "queuedomain" , Version = 1 } ;
118
142
// Act
119
- KnownUser . CancelRequestByLocalConfig ( "url" , "queueitToken" , cancelEventConfig , "customerid" , "secretekey" ) ;
143
+ KnownUser . CancelRequestByLocalConfig ( "url" , "queueitToken" , cancelEventConfig , "customerid" , "secretekey" ) ;
120
144
121
145
// Assert
122
146
Assert . Equal ( "url" , mock . cancelRequestCalls [ 0 ] [ 0 ] ) ;
@@ -187,7 +211,7 @@ public void CancelRequestByLocalConfig_CancelEventConfigNull_Test()
187
211
UserInQueueServiceMock mock = new UserInQueueServiceMock ( ) ;
188
212
KnownUser . _UserInQueueService = ( mock ) ;
189
213
bool exceptionWasThrown = false ;
190
-
214
+
191
215
// Act
192
216
try
193
217
{
@@ -771,7 +795,7 @@ public void ValidateRequestByIntegrationConfig_CancelAction()
771
795
772
796
UserInQueueServiceMock mock = new UserInQueueServiceMock ( ) ;
773
797
KnownUser . _UserInQueueService = ( mock ) ;
774
- // Act
798
+ // Act
775
799
KnownUser . ValidateRequestByIntegrationConfig ( "http://test.com?event1=true" , "queueitToken" , customerIntegration , "customerid" , "secretkey" ) ;
776
800
777
801
// Assert
@@ -785,25 +809,39 @@ public void ValidateRequestByIntegrationConfig_CancelAction()
785
809
public void ValidateRequestByIntegrationConfig_Debug ( )
786
810
{
787
811
// Arrange
812
+ string requestIP = "80.35.35.34" ;
813
+ string viaHeader = "1.1 example.com" ;
814
+ string forwardedHeader = "for=192.0.2.60;proto=http;by=203.0.113.43" ;
815
+ string xForwardedForHeader = "129.78.138.66, 129.78.64.103" ;
816
+ string xForwardedHostHeader = "en.wikipedia.org:8080" ;
817
+ string xForwardedProtoHeader = "https" ;
818
+
788
819
var httpContextMock = new HttpContextMock ( )
789
820
{
790
821
MockRequest = new MockHttpRequest ( )
791
822
{
823
+ HeadersValue = new NameValueCollection ( ) {
824
+ { "Via" , viaHeader } ,
825
+ { "Forwarded" , forwardedHeader } ,
826
+ { "X-Forwarded-For" , xForwardedForHeader } ,
827
+ { "X-Forwarded-Host" , xForwardedHostHeader } ,
828
+ { "X-Forwarded-Proto" , xForwardedProtoHeader }
829
+ } ,
830
+ UserHostAddressValue = requestIP ,
792
831
QueryStringValue = new NameValueCollection ( )
793
832
{
794
- { "queueittoken" , "queueittoken_value" } ,
795
- { "queueitdebug" , "queueitdebug_value" }
796
-
833
+ { "queueittoken" , "queueittoken_value" } ,
834
+ { "queueitdebug" , "queueitdebug_value" }
797
835
} ,
798
836
UrlValue = new Uri ( "http://test.com/?event1=true&queueittoken=queueittokenvalue" ) ,
799
837
CookiesValue = new HttpCookieCollection ( )
800
- }
801
- ,
838
+ } ,
802
839
MockResponse = new MockHttpResponse ( )
803
840
{
804
841
CookiesValue = new HttpCookieCollection ( )
805
842
}
806
843
} ;
844
+
807
845
KnownUser . _HttpContextBase = httpContextMock ;
808
846
UserInQueueServiceMock mock = new UserInQueueServiceMock ( ) ;
809
847
KnownUser . _UserInQueueService = ( mock ) ;
@@ -816,8 +854,6 @@ public void ValidateRequestByIntegrationConfig_Debug()
816
854
triggerPart1 . IsNegative = false ;
817
855
triggerPart1 . IsIgnoreCase = true ;
818
856
819
-
820
-
821
857
TriggerModel trigger = new TriggerModel ( ) ;
822
858
trigger . LogicalOperator = "And" ;
823
859
trigger . TriggerParts = new TriggerPart [ ] { triggerPart1 } ;
@@ -841,11 +877,11 @@ public void ValidateRequestByIntegrationConfig_Debug()
841
877
customerIntegration . Version = 3 ;
842
878
var queueitToken = QueueITTokenGenerator . GenerateToken ( DateTime . UtcNow , "event1" ,
843
879
Guid . NewGuid ( ) . ToString ( ) , true , null , "secretKey" , out var hash , "debug" ) ;
844
-
880
+
881
+ var utcTimeBeforeActionWasPerformed = DateTime . UtcNow . ToString ( "o" ) ;
882
+
845
883
// Act
846
- RequestValidationResult result = KnownUser
847
- . ValidateRequestByIntegrationConfig ( $ "http://test.com?event1=true",
848
- queueitToken , customerIntegration , "customerId" , "secretKey" ) ;
884
+ RequestValidationResult result = KnownUser . ValidateRequestByIntegrationConfig ( $ "http://test.com?event1=true", queueitToken , customerIntegration , "customerId" , "secretKey" ) ;
849
885
850
886
// Assert
851
887
var cookieValues = HttpUtility . UrlDecode ( httpContextMock . MockResponse . Cookies [ "queueitdebug" ] . Value ) . Split ( '|' ) ;
@@ -855,17 +891,35 @@ public void ValidateRequestByIntegrationConfig_Debug()
855
891
Assert . True ( cookieValues . Any ( v => v == $ "QueueitToken={ queueitToken } ") ) ;
856
892
Assert . True ( cookieValues . Any ( v => v == $ "OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue") ) ;
857
893
Assert . True ( cookieValues . Any ( v => v == $ "TargetUrl=http://test.com?event1=true") ) ;
858
- Assert . True ( cookieValues . Any ( v => v == $ "QueueConfig=EventId:event1&Version:3&QueueDomain:knownusertest.queue-it.net&CookieDomain:.test.com&ExtendCookieValidity:True&CookieValidityMinute:20&LayoutName:Christmas Layout by Queue-it&Culture:da-DK") ) ;
859
- }
894
+ Assert . True ( cookieValues . Any ( v => v == $ "QueueConfig=EventId:event1&Version:3&QueueDomain:knownusertest.queue-it.net&CookieDomain:.test.com&ExtendCookieValidity:True&CookieValidityMinute:20&LayoutName:Christmas Layout by Queue-it&Culture:da-DK") ) ;
860
895
896
+ AssertRequestCookieContent ( cookieValues ,
897
+ utcTimeBeforeActionWasPerformed , requestIP , viaHeader , forwardedHeader , xForwardedForHeader , xForwardedHostHeader , xForwardedProtoHeader ) ;
898
+ }
899
+
861
900
[ Fact ]
862
901
public void ValidateRequestByIntegrationConfig_Debug_WithoutMatch ( )
863
902
{
864
903
// Arrange
904
+ string requestIP = "80.35.35.34" ;
905
+ string viaHeader = "1.1 example.com" ;
906
+ string forwardedHeader = "for=192.0.2.60;proto=http;by=203.0.113.43" ;
907
+ string xForwardedForHeader = "129.78.138.66, 129.78.64.103" ;
908
+ string xForwardedHostHeader = "en.wikipedia.org:8080" ;
909
+ string xForwardedProtoHeader = "https" ;
910
+
865
911
var httpContextMock = new HttpContextMock ( )
866
912
{
867
913
MockRequest = new MockHttpRequest ( )
868
914
{
915
+ HeadersValue = new NameValueCollection ( ) {
916
+ { "Via" , viaHeader } ,
917
+ { "Forwarded" , forwardedHeader } ,
918
+ { "X-Forwarded-For" , xForwardedForHeader } ,
919
+ { "X-Forwarded-Host" , xForwardedHostHeader } ,
920
+ { "X-Forwarded-Proto" , xForwardedProtoHeader }
921
+ } ,
922
+ UserHostAddressValue = requestIP ,
869
923
QueryStringValue = new NameValueCollection ( )
870
924
{
871
925
{ "queueittoken" , "queueittoken_value" } ,
@@ -891,6 +945,9 @@ public void ValidateRequestByIntegrationConfig_Debug_WithoutMatch()
891
945
892
946
var queueitToken = QueueITTokenGenerator . GenerateToken ( DateTime . UtcNow , "event1" ,
893
947
Guid . NewGuid ( ) . ToString ( ) , true , null , "secretKey" , out var hash , "debug" ) ;
948
+
949
+ var utcTimeBeforeActionWasPerformed = DateTime . UtcNow . ToString ( "o" ) ;
950
+
894
951
// Act
895
952
RequestValidationResult result = KnownUser
896
953
. ValidateRequestByIntegrationConfig ( "http://test.com?event1=true" ,
@@ -903,6 +960,9 @@ public void ValidateRequestByIntegrationConfig_Debug_WithoutMatch()
903
960
Assert . True ( cookieValues . Any ( v => v == $ "ConfigVersion=10") ) ;
904
961
Assert . True ( cookieValues . Any ( v => v == $ "OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue") ) ;
905
962
Assert . True ( cookieValues . Any ( v => v == $ "MatchedConfig=NULL") ) ;
963
+
964
+ AssertRequestCookieContent ( cookieValues ,
965
+ utcTimeBeforeActionWasPerformed , requestIP , viaHeader , forwardedHeader , xForwardedForHeader , xForwardedHostHeader , xForwardedProtoHeader ) ;
906
966
}
907
967
908
968
[ Fact ]
@@ -942,18 +1002,34 @@ public void ValidateRequestByIntegrationConfig_Debug_WithoutMatch_NotValidHash()
942
1002
// Act
943
1003
RequestValidationResult result = KnownUser
944
1004
. ValidateRequestByIntegrationConfig ( "http://test.com?event1=true" ,
945
- queueitToken + "test" , customerIntegration , "customerId" , "secretKey" ) ;
1005
+ queueitToken + "test" , customerIntegration , "customerId" , "secretKey" ) ;
946
1006
947
1007
Assert . True ( httpContextMock . MockResponse . Cookies . AllKeys . Length == 0 ) ;
948
1008
}
1009
+
949
1010
[ Fact ]
950
1011
public void ResolveQueueRequestByLocalConfig_Debug ( )
951
1012
{
952
1013
// Arrange
1014
+ string requestIP = "80.35.35.34" ;
1015
+ string viaHeader = "1.1 example.com" ;
1016
+ string forwardedHeader = "for=192.0.2.60;proto=http;by=203.0.113.43" ;
1017
+ string xForwardedForHeader = "129.78.138.66, 129.78.64.103" ;
1018
+ string xForwardedHostHeader = "en.wikipedia.org:8080" ;
1019
+ string xForwardedProtoHeader = "https" ;
1020
+
953
1021
var httpContextMock = new HttpContextMock ( )
954
1022
{
955
1023
MockRequest = new MockHttpRequest ( )
956
1024
{
1025
+ HeadersValue = new NameValueCollection ( ) {
1026
+ { "Via" , viaHeader } ,
1027
+ { "Forwarded" , forwardedHeader } ,
1028
+ { "X-Forwarded-For" , xForwardedForHeader } ,
1029
+ { "X-Forwarded-Host" , xForwardedHostHeader } ,
1030
+ { "X-Forwarded-Proto" , xForwardedProtoHeader }
1031
+ } ,
1032
+ UserHostAddressValue = requestIP ,
957
1033
QueryStringValue = new NameValueCollection ( )
958
1034
{
959
1035
{ "queueittoken" , "queueittoken_value" } ,
@@ -986,27 +1062,45 @@ public void ResolveQueueRequestByLocalConfig_Debug()
986
1062
var queueitToken = QueueITTokenGenerator . GenerateToken ( DateTime . UtcNow , "event1" ,
987
1063
Guid . NewGuid ( ) . ToString ( ) , true , null , "secretKey" , out var hash , "debug" ) ;
988
1064
1065
+ var utcTimeBeforeActionWasPerformed = DateTime . UtcNow . ToString ( "o" ) ;
1066
+
989
1067
// Act
990
- RequestValidationResult result = KnownUser
991
- . ResolveQueueRequestByLocalConfig ( "http://test.com?event1=true" ,
992
- queueitToken , eventConfig , "customerId" , "secretKey" ) ;
1068
+ RequestValidationResult result = KnownUser . ResolveQueueRequestByLocalConfig ( "http://test.com?event1=true" , queueitToken , eventConfig , "customerId" , "secretKey" ) ;
993
1069
994
1070
// Assert
995
1071
var cookieValues = HttpUtility . UrlDecode ( httpContextMock . MockResponse . Cookies [ "queueitdebug" ] . Value ) . Split ( '|' ) ;
996
1072
Assert . True ( cookieValues . Any ( v => v == $ "QueueitToken={ queueitToken } ") ) ;
997
1073
Assert . True ( cookieValues . Any ( v => v == $ "OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue") ) ;
998
1074
Assert . True ( cookieValues . Any ( v => v == $ "TargetUrl=http://test.com?event1=true") ) ;
999
- Assert . True ( cookieValues . Any ( v => v == $ "QueueConfig=EventId:eventId&Version:12&QueueDomain:queueDomain&CookieDomain:cookieDomain&ExtendCookieValidity:True&CookieValidityMinute:10&LayoutName:layoutName&Culture:culture") ) ;
1075
+ Assert . True ( cookieValues . Any ( v => v == $ "QueueConfig=EventId:eventId&Version:12&QueueDomain:queueDomain&CookieDomain:cookieDomain&ExtendCookieValidity:True&CookieValidityMinute:10&LayoutName:layoutName&Culture:culture") ) ;
1076
+
1077
+ AssertRequestCookieContent ( cookieValues ,
1078
+ utcTimeBeforeActionWasPerformed , requestIP , viaHeader , forwardedHeader , xForwardedForHeader , xForwardedHostHeader , xForwardedProtoHeader ) ;
1000
1079
}
1001
1080
1002
1081
[ Fact ]
1003
1082
public void CancelRequestByLocalConfig_Debug ( )
1004
1083
{
1005
1084
// Arrange
1085
+ string requestIP = "80.35.35.34" ;
1086
+ string viaHeader = "1.1 example.com" ;
1087
+ string forwardedHeader = "for=192.0.2.60;proto=http;by=203.0.113.43" ;
1088
+ string xForwardedForHeader = "129.78.138.66, 129.78.64.103" ;
1089
+ string xForwardedHostHeader = "en.wikipedia.org:8080" ;
1090
+ string xForwardedProtoHeader = "https" ;
1091
+
1006
1092
var httpContextMock = new HttpContextMock ( )
1007
1093
{
1008
1094
MockRequest = new MockHttpRequest ( )
1009
1095
{
1096
+ HeadersValue = new NameValueCollection ( ) {
1097
+ { "Via" , viaHeader } ,
1098
+ { "Forwarded" , forwardedHeader } ,
1099
+ { "X-Forwarded-For" , xForwardedForHeader } ,
1100
+ { "X-Forwarded-Host" , xForwardedHostHeader } ,
1101
+ { "X-Forwarded-Proto" , xForwardedProtoHeader }
1102
+ } ,
1103
+ UserHostAddressValue = requestIP ,
1010
1104
QueryStringValue = new NameValueCollection ( )
1011
1105
{
1012
1106
{ "queueittoken" , "queueittoken_value" } ,
@@ -1036,17 +1130,20 @@ public void CancelRequestByLocalConfig_Debug()
1036
1130
var queueitToken = QueueITTokenGenerator . GenerateToken ( DateTime . UtcNow , "event1" ,
1037
1131
Guid . NewGuid ( ) . ToString ( ) , true , null , "secretKey" , out var hash , "debug" ) ;
1038
1132
1133
+ var utcTimeBeforeActionWasPerformed = DateTime . UtcNow . ToString ( "o" ) ;
1134
+
1039
1135
// Act
1040
- RequestValidationResult result = KnownUser
1041
- . CancelRequestByLocalConfig ( "http://test.com?event1=true" ,
1042
- queueitToken , eventConfig , "customerId" , "secretKey" ) ;
1136
+ RequestValidationResult result = KnownUser . CancelRequestByLocalConfig ( "http://test.com?event1=true" , queueitToken , eventConfig , "customerId" , "secretKey" ) ;
1043
1137
1044
1138
// Assert
1045
1139
var cookieValues = HttpUtility . UrlDecode ( httpContextMock . MockResponse . Cookies [ "queueitdebug" ] . Value ) . Split ( '|' ) ;
1046
1140
Assert . True ( cookieValues . Any ( v => v == $ "QueueitToken={ queueitToken } ") ) ;
1047
1141
Assert . True ( cookieValues . Any ( v => v == $ "OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue") ) ;
1048
1142
Assert . True ( cookieValues . Any ( v => v == $ "TargetUrl=http://test.com?event1=true") ) ;
1049
1143
Assert . True ( cookieValues . Any ( v => v == $ "CancelConfig=EventId:eventId&Version:12&QueueDomain:queueDomain&CookieDomain:cookieDomain") ) ;
1144
+
1145
+ AssertRequestCookieContent ( cookieValues ,
1146
+ utcTimeBeforeActionWasPerformed , requestIP , viaHeader , forwardedHeader , xForwardedForHeader , xForwardedHostHeader , xForwardedProtoHeader ) ;
1050
1147
}
1051
1148
}
1052
1149
}
0 commit comments