1
1
// Copyright (c) Umbraco.
2
2
// See LICENSE for more details.
3
3
4
- using System . Collections . Generic ;
5
4
using System . Security . Claims ;
6
- using System . Threading . Tasks ;
7
5
using Microsoft . AspNetCore . Authorization ;
8
6
using Microsoft . AspNetCore . Http ;
9
7
using Microsoft . Extensions . Primitives ;
@@ -34,7 +32,7 @@ public class ContentPermissionsQueryStringHandlerTests
34
32
public async Task Node_Id_From_Requirement_With_Permission_Is_Authorized ( )
35
33
{
36
34
var authHandlerContext = CreateAuthorizationHandlerContext ( NodeId ) ;
37
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( ) ;
35
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( ) ;
38
36
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "A" } ) ;
39
37
40
38
await sut . HandleAsync ( authHandlerContext ) ;
@@ -46,7 +44,7 @@ public async Task Node_Id_From_Requirement_With_Permission_Is_Authorized()
46
44
public async Task Node_Id_From_Requirement_Without_Permission_Is_Not_Authorized ( )
47
45
{
48
46
var authHandlerContext = CreateAuthorizationHandlerContext ( NodeId ) ;
49
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( ) ;
47
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( ) ;
50
48
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "B" } ) ;
51
49
52
50
await sut . HandleAsync ( authHandlerContext ) ;
@@ -59,7 +57,7 @@ public async Task Node_Id_From_Requirement_Without_Permission_Is_Not_Authorized(
59
57
public async Task Node_Id_Missing_From_Requirement_And_QueryString_Is_Authorized ( )
60
58
{
61
59
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
62
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( "xxx" ) ;
60
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( "xxx" ) ;
63
61
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "A" } ) ;
64
62
65
63
await sut . HandleAsync ( authHandlerContext ) ;
@@ -71,7 +69,7 @@ public async Task Node_Id_Missing_From_Requirement_And_QueryString_Is_Authorized
71
69
public async Task Node_Integer_Id_From_QueryString_With_Permission_Is_Authorized ( )
72
70
{
73
71
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
74
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( queryStringValue : NodeId . ToString ( ) ) ;
72
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( queryStringValue : NodeId . ToString ( ) ) ;
75
73
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "A" } ) ;
76
74
77
75
await sut . HandleAsync ( authHandlerContext ) ;
@@ -84,7 +82,21 @@ public async Task Node_Integer_Id_From_QueryString_With_Permission_Is_Authorized
84
82
public async Task Node_Integer_Id_From_QueryString_Without_Permission_Is_Not_Authorized ( )
85
83
{
86
84
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
87
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( queryStringValue : NodeId . ToString ( ) ) ;
85
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( queryStringValue : NodeId . ToString ( ) ) ;
86
+ var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "B" } ) ;
87
+
88
+ await sut . HandleAsync ( authHandlerContext ) ;
89
+
90
+ Assert . IsFalse ( authHandlerContext . HasSucceeded ) ;
91
+ AssertContentCached ( mockHttpContextAccessor ) ;
92
+ }
93
+
94
+ [ Test ]
95
+ public async Task Node_Integer_Id_From_QueryString_Without_Permission_Is_Not_Authorized_Even_When_Additional_Parameter_For_Id_With_Permission_Is_Provided ( )
96
+ {
97
+ // Provides initially failing test and verifies fix for advisory https://github.com/umbraco/Umbraco-CMS/security/advisories/GHSA-wx5h-wqfq-v698
98
+ var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
99
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValues ( queryStringValues : [ NodeId . ToString ( ) , 1001 . ToString ( ) ] ) ;
88
100
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "B" } ) ;
89
101
90
102
await sut . HandleAsync ( authHandlerContext ) ;
@@ -97,7 +109,7 @@ public async Task Node_Integer_Id_From_QueryString_Without_Permission_Is_Not_Aut
97
109
public async Task Node_Udi_Id_From_QueryString_With_Permission_Is_Authorized ( )
98
110
{
99
111
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
100
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( queryStringValue : s_nodeUdi . ToString ( ) ) ;
112
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( queryStringValue : s_nodeUdi . ToString ( ) ) ;
101
113
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "A" } ) ;
102
114
103
115
await sut . HandleAsync ( authHandlerContext ) ;
@@ -110,7 +122,7 @@ public async Task Node_Udi_Id_From_QueryString_With_Permission_Is_Authorized()
110
122
public async Task Node_Udi_Id_From_QueryString_Without_Permission_Is_Not_Authorized ( )
111
123
{
112
124
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
113
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( queryStringValue : s_nodeUdi . ToString ( ) ) ;
125
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( queryStringValue : s_nodeUdi . ToString ( ) ) ;
114
126
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "B" } ) ;
115
127
116
128
await sut . HandleAsync ( authHandlerContext ) ;
@@ -123,7 +135,7 @@ public async Task Node_Udi_Id_From_QueryString_Without_Permission_Is_Not_Authori
123
135
public async Task Node_Guid_Id_From_QueryString_With_Permission_Is_Authorized ( )
124
136
{
125
137
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
126
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( queryStringValue : s_nodeGuid . ToString ( ) ) ;
138
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( queryStringValue : s_nodeGuid . ToString ( ) ) ;
127
139
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "A" } ) ;
128
140
129
141
await sut . HandleAsync ( authHandlerContext ) ;
@@ -136,7 +148,7 @@ public async Task Node_Guid_Id_From_QueryString_With_Permission_Is_Authorized()
136
148
public async Task Node_Guid_Id_From_QueryString_Without_Permission_Is_Not_Authorized ( )
137
149
{
138
150
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
139
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( queryStringValue : s_nodeGuid . ToString ( ) ) ;
151
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( queryStringValue : s_nodeGuid . ToString ( ) ) ;
140
152
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "B" } ) ;
141
153
142
154
await sut . HandleAsync ( authHandlerContext ) ;
@@ -149,7 +161,7 @@ public async Task Node_Guid_Id_From_QueryString_Without_Permission_Is_Not_Author
149
161
public async Task Node_Invalid_Id_From_QueryString_Is_Authorized ( )
150
162
{
151
163
var authHandlerContext = CreateAuthorizationHandlerContext ( ) ;
152
- var mockHttpContextAccessor = CreateMockHttpContextAccessor ( queryStringValue : "invalid" ) ;
164
+ var mockHttpContextAccessor = CreateMockHttpContextAccessorWithQueryStringValue ( queryStringValue : "invalid" ) ;
153
165
var sut = CreateHandler ( mockHttpContextAccessor . Object , NodeId , new [ ] { "A" } ) ;
154
166
155
167
await sut . HandleAsync ( authHandlerContext ) ;
@@ -168,14 +180,20 @@ private static AuthorizationHandlerContext CreateAuthorizationHandlerContext(int
168
180
return new AuthorizationHandlerContext ( new List < IAuthorizationRequirement > { requirement } , user , resource ) ;
169
181
}
170
182
171
- private static Mock < IHttpContextAccessor > CreateMockHttpContextAccessor (
183
+ private static Mock < IHttpContextAccessor > CreateMockHttpContextAccessorWithQueryStringValue (
172
184
string queryStringName = QueryStringName ,
173
185
string queryStringValue = "" )
186
+ => CreateMockHttpContextAccessorWithQueryStringValues ( queryStringName , [ queryStringValue ] ) ;
187
+
188
+ private static Mock < IHttpContextAccessor > CreateMockHttpContextAccessorWithQueryStringValues (
189
+ string queryStringName = QueryStringName ,
190
+ string [ ] ? queryStringValues = null )
174
191
{
192
+ queryStringValues ??= [ ] ;
175
193
var mockHttpContextAccessor = new Mock < IHttpContextAccessor > ( ) ;
176
194
var mockHttpContext = new Mock < HttpContext > ( ) ;
177
195
var mockHttpRequest = new Mock < HttpRequest > ( ) ;
178
- var queryParams = new Dictionary < string , StringValues > { { queryStringName , queryStringValue } } ;
196
+ var queryParams = new Dictionary < string , StringValues > { { queryStringName , new StringValues ( queryStringValues ) } } ;
179
197
mockHttpRequest . SetupGet ( x => x . Query ) . Returns ( new QueryCollection ( queryParams ) ) ;
180
198
mockHttpContext . SetupGet ( x => x . Request ) . Returns ( mockHttpRequest . Object ) ;
181
199
mockHttpContext . SetupGet ( x => x . Items ) . Returns ( new Dictionary < object , object > ( ) ) ;
0 commit comments