@@ -5,11 +5,11 @@ namespace Microsoft.SCIM.WebHostSample.Provider
55 using System ;
66 using System . Collections . Generic ;
77 using System . Linq ;
8+ using System . Linq . Expressions ;
89 using System . Net ;
910 using System . Threading . Tasks ;
1011 using System . Web . Http ;
1112 using Microsoft . SCIM ;
12- using Microsoft . SCIM . WebHostSample . Resources ;
1313
1414 public class InMemoryGroupProvider : ProviderBase
1515 {
@@ -44,6 +44,10 @@ public override Task<Resource> CreateAsync(Resource resource, string correlation
4444 {
4545 throw new HttpResponseException ( HttpStatusCode . Conflict ) ;
4646 }
47+ //Update Metadata
48+ DateTime created = DateTime . UtcNow ;
49+ group . Metadata . Created = created ;
50+ group . Metadata . LastModified = created ;
4751
4852 string resourceIdentifier = Guid . NewGuid ( ) . ToString ( ) ;
4953 resource . Identifier = resourceIdentifier ;
@@ -83,83 +87,61 @@ public override Task<Resource[]> QueryAsync(IQueryParameters parameters, string
8387
8488 if ( null == parameters . AlternateFilters )
8589 {
86- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
90+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
8791 }
8892
8993 if ( string . IsNullOrWhiteSpace ( parameters . SchemaIdentifier ) )
9094 {
91- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
95+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
9296 }
9397
94- Resource [ ] results ;
98+ IEnumerable < Resource > results ;
9599 IFilter queryFilter = parameters . AlternateFilters . SingleOrDefault ( ) ;
96- IEnumerable < Core2Group > buffer = Enumerable . Empty < Core2Group > ( ) ;
100+
101+ var predicate = PredicateBuilder . False < Core2Group > ( ) ;
102+ Expression < Func < Core2Group , bool > > predicateAnd ;
103+ predicateAnd = PredicateBuilder . True < Core2Group > ( ) ;
104+
97105 if ( queryFilter == null )
98106 {
99- buffer = this . storage . Groups . Values ;
107+ results = this . storage . Groups . Values . Select (
108+ ( Core2Group user ) => user as Resource ) ;
100109 }
101110 else
102111 {
103112 if ( string . IsNullOrWhiteSpace ( queryFilter . AttributePath ) )
104113 {
105- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
114+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
106115 }
107116
108117 if ( string . IsNullOrWhiteSpace ( queryFilter . ComparisonValue ) )
109118 {
110- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidParameters ) ;
119+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidParameters ) ;
111120 }
112121
113122 if ( queryFilter . FilterOperator != ComparisonOperator . Equals )
114123 {
115- throw new NotSupportedException ( SampleServiceResources . UnsupportedComparisonOperator ) ;
124+ throw new NotSupportedException ( string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterOperatorNotSupportedTemplate , queryFilter . FilterOperator ) ) ;
116125 }
117126
127+
118128 if ( queryFilter . AttributePath . Equals ( AttributeNames . DisplayName ) )
119129 {
120- buffer =
121- this . storage . Groups . Values
122- . Where (
123- ( Core2Group item ) =>
124- string . Equals (
125- item . DisplayName ,
126- parameters . AlternateFilters . Single ( ) . ComparisonValue ,
127- StringComparison . OrdinalIgnoreCase ) ) ;
130+
131+ string displayName = queryFilter . ComparisonValue ;
132+ predicateAnd = predicateAnd . And ( p => string . Equals ( p . DisplayName , displayName , StringComparison . OrdinalIgnoreCase ) ) ;
133+
128134 }
129135 else
130136 {
131- throw new NotSupportedException ( SampleServiceResources . UnsupportedFilterAttributeGroup ) ;
137+ throw new NotSupportedException ( string . Format ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionFilterAttributePathNotSupportedTemplate , queryFilter . AttributePath ) ) ;
132138 }
133139 }
140+
141+ predicate = predicate . Or ( predicateAnd ) ;
142+ results = this . storage . Groups . Values . Where ( predicate . Compile ( ) ) ;
134143
135- results =
136- buffer
137- . Select ( ( Core2Group item ) =>
138- {
139- Core2Group bufferItem =
140- new Core2Group
141- {
142- DisplayName = item . DisplayName ,
143- ExternalIdentifier = item . ExternalIdentifier ,
144- Identifier = item . Identifier ,
145- Members = item . Members ,
146- Metadata = item . Metadata
147- } ;
148-
149- if ( parameters ? . ExcludedAttributePaths ? . Any (
150- ( string excludedAttributes ) =>
151- excludedAttributes . Equals ( AttributeNames . Members , StringComparison . OrdinalIgnoreCase ) )
152- == true )
153- {
154- bufferItem . Members = null ;
155- }
156-
157- return bufferItem ;
158- } )
159- . Select ( ( Core2Group item ) => item as Resource )
160- . ToArray ( ) ;
161-
162- return Task . FromResult ( results ) ;
144+ return Task . FromResult ( results . ToArray ( ) ) ;
163145 }
164146
165147 public override Task < Resource > ReplaceAsync ( Resource resource , string correlationIdentifier )
@@ -176,10 +158,10 @@ public override Task<Resource> ReplaceAsync(Resource resource, string correlatio
176158 throw new HttpResponseException ( HttpStatusCode . BadRequest ) ;
177159 }
178160
179- IEnumerable < Core2Group > exisitingGroups = this . storage . Groups . Values ;
161+ Core2Group exisitingGroups = resource as Core2Group ;
180162 if
181163 (
182- exisitingGroups . Any (
164+ this . storage . Groups . Values . Any (
183165 ( Core2Group exisitingUser ) =>
184166 string . Equals ( exisitingUser . DisplayName , group . DisplayName , StringComparison . Ordinal ) &&
185167 ! string . Equals ( exisitingUser . Identifier , group . Identifier , StringComparison . OrdinalIgnoreCase ) )
@@ -193,6 +175,10 @@ public override Task<Resource> ReplaceAsync(Resource resource, string correlatio
193175 throw new HttpResponseException ( HttpStatusCode . NotFound ) ;
194176 }
195177
178+ // Update metadata
179+ group . Metadata . Created = exisitingGroups . Metadata . Created ;
180+ group . Metadata . LastModified = DateTime . UtcNow ;
181+
196182 this . storage . Groups [ group . Identifier ] = group ;
197183 Resource result = group as Resource ;
198184 return Task . FromResult ( result ) ;
@@ -238,17 +224,17 @@ public override Task UpdateAsync(IPatch patch, string correlationIdentifier)
238224
239225 if ( null == patch . ResourceIdentifier )
240226 {
241- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidPatch ) ;
227+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidOperation ) ;
242228 }
243229
244230 if ( string . IsNullOrWhiteSpace ( patch . ResourceIdentifier . Identifier ) )
245231 {
246- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidPatch ) ;
232+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidOperation ) ;
247233 }
248234
249235 if ( null == patch . PatchRequest )
250236 {
251- throw new ArgumentException ( SampleServiceResources . ExceptionInvalidPatch ) ;
237+ throw new ArgumentException ( SystemForCrossDomainIdentityManagementServiceResources . ExceptionInvalidOperation ) ;
252238 }
253239
254240 PatchRequest2 patchRequest =
@@ -263,6 +249,8 @@ public override Task UpdateAsync(IPatch patch, string correlationIdentifier)
263249 if ( this . storage . Groups . TryGetValue ( patch . ResourceIdentifier . Identifier , out Core2Group group ) )
264250 {
265251 group . Apply ( patchRequest ) ;
252+ // Update metadata
253+ group . Metadata . LastModified = DateTime . UtcNow ;
266254 }
267255 else
268256 {
0 commit comments