@@ -9,7 +9,6 @@ namespace Microsoft.SCIM.WebHostSample.Provider
9
9
using System . Threading . Tasks ;
10
10
using System . Web . Http ;
11
11
using Microsoft . SCIM ;
12
- using Microsoft . SCIM . WebHostSample . Resources ;
13
12
14
13
public class InMemoryUserProvider : ProviderBase
15
14
{
@@ -44,6 +43,11 @@ public override Task<Resource> CreateAsync(Resource resource, string correlation
44
43
throw new HttpResponseException ( HttpStatusCode . Conflict ) ;
45
44
}
46
45
46
+ // Update metadata
47
+ DateTime created = DateTime . UtcNow ;
48
+ user . Metadata . Created = created ;
49
+ user . Metadata . LastModified = created ;
50
+
47
51
string resourceIdentifier = Guid . NewGuid ( ) . ToString ( ) ;
48
52
resource . Identifier = resourceIdentifier ;
49
53
this . storage . Users . Add ( resourceIdentifier , user ) ;
@@ -82,71 +86,153 @@ public override Task<Resource[]> QueryAsync(IQueryParameters parameters, string
82
86
83
87
if ( null == parameters . AlternateFilters )
84
88
{
85
- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
89
+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
86
90
}
87
91
88
92
if ( string . IsNullOrWhiteSpace ( parameters . SchemaIdentifier ) )
89
93
{
90
- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
94
+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
91
95
}
92
96
93
- Resource [ ] results ;
94
- IFilter queryFilter = parameters . AlternateFilters . SingleOrDefault ( ) ;
95
- if ( queryFilter == null )
96
- {
97
- IEnumerable < Core2EnterpriseUser > allUsers = this . storage . Users . Values ;
98
- results =
99
- allUsers . Select ( ( Core2EnterpriseUser user ) => user as Resource ) . ToArray ( ) ;
100
-
101
- return Task . FromResult ( results ) ;
102
- }
103
-
104
- if ( string . IsNullOrWhiteSpace ( queryFilter . AttributePath ) )
105
- {
106
- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
107
- }
97
+ IEnumerable < Resource > results = new List < Core2EnterpriseUser > ( ) ;
108
98
109
- if ( string . IsNullOrWhiteSpace ( queryFilter . ComparisonValue ) )
99
+ if ( parameters . AlternateFilters . Count <= 0 )
110
100
{
111
- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
101
+ results = this . storage . Users . Values . Select (
102
+ ( Core2EnterpriseUser user ) => user as Resource ) ;
112
103
}
113
-
114
- if ( queryFilter . FilterOperator != ComparisonOperator . Equals )
104
+ else
115
105
{
116
- throw new NotSupportedException ( SampleServiceResources . UnsupportedComparisonOperator ) ;
117
- }
106
+ results = new List < Core2EnterpriseUser > ( ) ;
118
107
119
- if ( queryFilter . AttributePath . Equals ( AttributeNames . UserName ) )
120
- {
121
- IEnumerable < Core2EnterpriseUser > allUsers = this . storage . Users . Values ;
122
- results =
123
- allUsers . Where (
124
- ( Core2EnterpriseUser item ) =>
125
- string . Equals (
126
- item . UserName ,
127
- parameters . AlternateFilters . Single ( ) . ComparisonValue ,
128
- StringComparison . OrdinalIgnoreCase ) )
129
- . Select ( ( Core2EnterpriseUser user ) => user as Resource ) . ToArray ( ) ;
130
-
131
- return Task . FromResult ( results ) ;
108
+ foreach ( IFilter queryFilter in parameters . AlternateFilters )
109
+ {
110
+ IEnumerable < Core2EnterpriseUser > users = this . storage . Users . Values ;
111
+
112
+ IFilter andFilter = queryFilter ;
113
+ IFilter currentFilter = andFilter ;
114
+ do
115
+ {
116
+ if ( string . IsNullOrWhiteSpace ( andFilter . AttributePath ) )
117
+ {
118
+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
119
+ }
120
+
121
+ else if ( string . IsNullOrWhiteSpace ( andFilter . ComparisonValue ) )
122
+ {
123
+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
124
+ }
125
+
126
+ // UserName filter
127
+ else if ( andFilter . AttributePath . Equals ( AttributeNames . UserName , StringComparison . OrdinalIgnoreCase ) )
128
+ {
129
+ if ( andFilter . FilterOperator != ComparisonOperator . Equals )
130
+ {
131
+ throw new NotSupportedException (
132
+ string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterOperatorNotSupportedTemplate , andFilter . FilterOperator ) ) ;
133
+ }
134
+
135
+ users =
136
+ users . Where (
137
+ item =>
138
+ string . Equals (
139
+ item . UserName ,
140
+ andFilter . ComparisonValue ,
141
+ StringComparison . OrdinalIgnoreCase ) ) ;
142
+ }
143
+
144
+ // ExternalId filter
145
+ else if ( andFilter . AttributePath . Equals ( AttributeNames . ExternalIdentifier , StringComparison . OrdinalIgnoreCase ) )
146
+ {
147
+ if ( andFilter . FilterOperator != ComparisonOperator . Equals )
148
+ {
149
+ throw new NotSupportedException (
150
+ string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterOperatorNotSupportedTemplate , andFilter . FilterOperator ) ) ;
151
+ }
152
+
153
+ users =
154
+ users . Where (
155
+ item =>
156
+ string . Equals (
157
+ item . ExternalIdentifier ,
158
+ andFilter . ComparisonValue ,
159
+ StringComparison . OrdinalIgnoreCase ) ) . ToList ( ) ;
160
+ }
161
+
162
+ // Id filter
163
+ else if ( andFilter . AttributePath . Equals ( AttributeNames . Identifier , StringComparison . OrdinalIgnoreCase ) )
164
+ {
165
+ if ( andFilter . FilterOperator != ComparisonOperator . Equals )
166
+ {
167
+ throw new NotSupportedException (
168
+ string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterOperatorNotSupportedTemplate , andFilter . FilterOperator ) ) ;
169
+ }
170
+
171
+ users =
172
+ users . Where (
173
+ item =>
174
+ string . Equals (
175
+ item . Identifier ,
176
+ andFilter . ComparisonValue ,
177
+ StringComparison . OrdinalIgnoreCase ) ) . ToList ( ) ;
178
+ }
179
+
180
+ // Active filter
181
+ else if ( andFilter . AttributePath . Equals ( AttributeNames . Active , StringComparison . OrdinalIgnoreCase ) )
182
+ {
183
+ if ( andFilter . FilterOperator != ComparisonOperator . Equals )
184
+ {
185
+ throw new NotSupportedException (
186
+ string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterOperatorNotSupportedTemplate , andFilter . FilterOperator ) ) ;
187
+ }
188
+
189
+ users =
190
+ users . Where (
191
+ item =>
192
+ item . Active == bool . Parse ( andFilter . ComparisonValue ) ) . ToList ( ) ;
193
+ }
194
+
195
+ // LastModified filter
196
+ else if ( andFilter . AttributePath . Equals ( $ "{ AttributeNames . Metadata } .{ AttributeNames . LastModified } ", StringComparison . OrdinalIgnoreCase ) )
197
+ {
198
+ if ( andFilter . FilterOperator == ComparisonOperator . EqualOrGreaterThan )
199
+ {
200
+ users =
201
+ users . Where (
202
+ item =>
203
+ item . Metadata . LastModified >= DateTime . Parse ( andFilter . ComparisonValue ) . ToUniversalTime ( ) ) . ToList ( ) ;
204
+ }
205
+ else if ( andFilter . FilterOperator == ComparisonOperator . EqualOrLessThan )
206
+ {
207
+ users =
208
+ users . Where (
209
+ item =>
210
+ item . Metadata . LastModified <= DateTime . Parse ( andFilter . ComparisonValue ) . ToUniversalTime ( ) ) . ToList ( ) ;
211
+ }
212
+ else
213
+ throw new NotSupportedException (
214
+ string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterOperatorNotSupportedTemplate , andFilter . FilterOperator ) ) ;
215
+ }
216
+ else
217
+ throw new NotSupportedException (
218
+ string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterAttributePathNotSupportedTemplate , andFilter . AttributePath ) ) ;
219
+
220
+ currentFilter = andFilter ;
221
+ andFilter = andFilter . AdditionalFilter ;
222
+
223
+ } while ( currentFilter . AdditionalFilter != null ) ;
224
+
225
+ results = results . Union ( users . Select ( ( Core2EnterpriseUser user ) => user as Resource ) . ToList ( ) ) ;
226
+ }
132
227
}
133
228
134
- if ( queryFilter . AttributePath . Equals ( AttributeNames . ExternalIdentifier ) )
229
+ if ( parameters . PaginationParameters != null )
135
230
{
136
- IEnumerable < Core2EnterpriseUser > allUsers = this . storage . Users . Values ;
137
- results =
138
- allUsers . Where (
139
- ( Core2EnterpriseUser item ) =>
140
- string . Equals (
141
- item . ExternalIdentifier ,
142
- parameters . AlternateFilters . Single ( ) . ComparisonValue ,
143
- StringComparison . OrdinalIgnoreCase ) )
144
- . Select ( ( Core2EnterpriseUser user ) => user as Resource ) . ToArray ( ) ;
145
-
146
- return Task . FromResult ( results ) ;
231
+ int count = parameters . PaginationParameters . Count . HasValue ? parameters . PaginationParameters . Count . Value : 0 ;
232
+ return Task . FromResult ( results . Take ( count ) . ToArray ( ) ) ;
147
233
}
148
-
149
- throw new NotSupportedException ( SampleServiceResources . UnsupportedFilterAttributeUser ) ;
234
+ else
235
+ return Task . FromResult ( results . ToArray ( ) ) ;
150
236
}
151
237
152
238
public override Task < Resource > ReplaceAsync ( Resource resource , string correlationIdentifier )
@@ -163,10 +249,9 @@ public override Task<Resource> ReplaceAsync(Resource resource, string correlatio
163
249
throw new HttpResponseException ( HttpStatusCode . BadRequest ) ;
164
250
}
165
251
166
- IEnumerable < Core2EnterpriseUser > exisitingUsers = this . storage . Users . Values ;
167
252
if
168
253
(
169
- exisitingUsers . Any (
254
+ this . storage . Users . Values . Any (
170
255
( Core2EnterpriseUser exisitingUser ) =>
171
256
string . Equals ( exisitingUser . UserName , user . UserName , StringComparison . Ordinal ) &&
172
257
! string . Equals ( exisitingUser . Identifier , user . Identifier , StringComparison . OrdinalIgnoreCase ) )
@@ -175,11 +260,20 @@ public override Task<Resource> ReplaceAsync(Resource resource, string correlatio
175
260
throw new HttpResponseException ( HttpStatusCode . Conflict ) ;
176
261
}
177
262
178
- if ( ! this . storage . Users . TryGetValue ( user . Identifier , out Core2EnterpriseUser _ ) )
263
+ Core2EnterpriseUser exisitingUser = this . storage . Users . Values
264
+ . FirstOrDefault (
265
+ ( Core2EnterpriseUser exisitingUser ) =>
266
+ string . Equals ( exisitingUser . Identifier , user . Identifier , StringComparison . OrdinalIgnoreCase )
267
+ ) ;
268
+ if ( exisitingUser == null )
179
269
{
180
270
throw new HttpResponseException ( HttpStatusCode . NotFound ) ;
181
271
}
182
272
273
+ // Update metadata
274
+ user . Metadata . Created = exisitingUser . Metadata . Created ;
275
+ user . Metadata . LastModified = DateTime . UtcNow ;
276
+
183
277
this . storage . Users [ user . Identifier ] = user ;
184
278
Resource result = user as Resource ;
185
279
return Task . FromResult ( result ) ;
@@ -226,17 +320,17 @@ public override Task UpdateAsync(IPatch patch, string correlationIdentifier)
226
320
227
321
if ( null == patch . ResourceIdentifier )
228
322
{
229
- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidPatch ) ;
323
+ throw new ArgumentException ( string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidOperation ) ) ;
230
324
}
231
325
232
326
if ( string . IsNullOrWhiteSpace ( patch . ResourceIdentifier . Identifier ) )
233
327
{
234
- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidPatch ) ;
328
+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidOperation ) ;
235
329
}
236
330
237
331
if ( null == patch . PatchRequest )
238
332
{
239
- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidPatch ) ;
333
+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidOperation ) ;
240
334
}
241
335
242
336
PatchRequest2 patchRequest =
@@ -251,6 +345,9 @@ public override Task UpdateAsync(IPatch patch, string correlationIdentifier)
251
345
if ( this . storage . Users . TryGetValue ( patch . ResourceIdentifier . Identifier , out Core2EnterpriseUser user ) )
252
346
{
253
347
user . Apply ( patchRequest ) ;
348
+
349
+ // Update metadata
350
+ user . Metadata . LastModified = DateTime . UtcNow ;
254
351
}
255
352
else
256
353
{
0 commit comments