Skip to content

Commit 8120408

Browse files
committed
Added new aspnetcore startup project and moved hosting code out of the SCIM project
1 parent 95c923b commit 8120408

File tree

13 files changed

+1094
-2
lines changed

13 files changed

+1094
-2
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<ProjectReference Include="..\Microsoft.SystemForCrossDomainIdentityManagement\Microsoft.SCIM.csproj" />
9+
</ItemGroup>
10+
11+
</Project>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Hosting;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.Hosting;
8+
using Microsoft.Extensions.Logging;
9+
10+
namespace Microsoft.SCIM.WebHostSample
11+
{
12+
public class Program
13+
{
14+
public static void Main(string[] args)
15+
{
16+
CreateHostBuilder(args).Build().Run();
17+
}
18+
19+
public static IHostBuilder CreateHostBuilder(string[] args) =>
20+
Host.CreateDefaultBuilder(args)
21+
.ConfigureWebHostDefaults(webBuilder =>
22+
{
23+
webBuilder.UseStartup<Startup>();
24+
});
25+
}
26+
}
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
//------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation. All rights reserved.
3+
//------------------------------------------------------------
4+
5+
namespace Microsoft.SCIM.WebHostSample.Provider
6+
{
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Net;
11+
using System.Threading.Tasks;
12+
using System.Web.Http;
13+
using Microsoft.SCIM;
14+
using Microsoft.SCIM.WebHostSample.Resources;
15+
16+
public class InMemoryGroupProvider : ProviderBase
17+
{
18+
private readonly InMemoryStorage storage;
19+
20+
public InMemoryGroupProvider()
21+
{
22+
this.storage = InMemoryStorage.Instance;
23+
}
24+
25+
public override Task<Resource> CreateAsync(Resource resource, string correlationIdentifier)
26+
{
27+
if (resource.Identifier != null)
28+
{
29+
throw new HttpResponseException(HttpStatusCode.BadRequest);
30+
}
31+
32+
Core2Group group = resource as Core2Group;
33+
34+
if (string.IsNullOrWhiteSpace(group.DisplayName))
35+
{
36+
throw new HttpResponseException(HttpStatusCode.BadRequest);
37+
}
38+
39+
IEnumerable<Core2Group> exisitingGroups = this.storage.Groups.Values;
40+
if
41+
(
42+
exisitingGroups.Any(
43+
(Core2Group exisitingGroup) =>
44+
string.Equals(exisitingGroup.DisplayName, group.DisplayName, StringComparison.Ordinal))
45+
)
46+
{
47+
throw new HttpResponseException(HttpStatusCode.Conflict);
48+
}
49+
50+
string resourceIdentifier = Guid.NewGuid().ToString();
51+
resource.Identifier = resourceIdentifier;
52+
this.storage.Groups.Add(resourceIdentifier, group);
53+
54+
return Task.FromResult(resource);
55+
}
56+
57+
public override Task DeleteAsync(IResourceIdentifier resourceIdentifier, string correlationIdentifier)
58+
{
59+
if (string.IsNullOrWhiteSpace(resourceIdentifier?.Identifier))
60+
{
61+
throw new HttpResponseException(HttpStatusCode.BadRequest);
62+
}
63+
64+
string identifier = resourceIdentifier.Identifier;
65+
66+
if (this.storage.Groups.ContainsKey(identifier))
67+
{
68+
this.storage.Groups.Remove(identifier);
69+
}
70+
71+
return Task.CompletedTask;
72+
}
73+
74+
public override Task<Resource[]> QueryAsync(IQueryParameters parameters, string correlationIdentifier)
75+
{
76+
if (parameters == null)
77+
{
78+
throw new ArgumentNullException(nameof(parameters));
79+
}
80+
81+
if (string.IsNullOrWhiteSpace(correlationIdentifier))
82+
{
83+
throw new ArgumentNullException(nameof(correlationIdentifier));
84+
}
85+
86+
if (null == parameters.AlternateFilters)
87+
{
88+
throw new ArgumentException(SampleServiceResources.ExceptionInvalidParameters);
89+
}
90+
91+
if (string.IsNullOrWhiteSpace(parameters.SchemaIdentifier))
92+
{
93+
throw new ArgumentException(SampleServiceResources.ExceptionInvalidParameters);
94+
}
95+
96+
Resource[] results;
97+
IFilter queryFilter = parameters.AlternateFilters.SingleOrDefault();
98+
IEnumerable<Core2Group> buffer = Enumerable.Empty<Core2Group>();
99+
if (queryFilter == null)
100+
{
101+
buffer = this.storage.Groups.Values;
102+
}
103+
else
104+
{
105+
if (string.IsNullOrWhiteSpace(queryFilter.AttributePath))
106+
{
107+
throw new ArgumentException(SampleServiceResources.ExceptionInvalidParameters);
108+
}
109+
110+
if (string.IsNullOrWhiteSpace(queryFilter.ComparisonValue))
111+
{
112+
throw new ArgumentException(SampleServiceResources.ExceptionInvalidParameters);
113+
}
114+
115+
if (queryFilter.FilterOperator != ComparisonOperator.Equals)
116+
{
117+
throw new NotSupportedException(SampleServiceResources.UnsupportedComparisonOperator);
118+
}
119+
120+
if (queryFilter.AttributePath.Equals(AttributeNames.DisplayName))
121+
{
122+
buffer =
123+
this.storage.Groups.Values
124+
.Where(
125+
(Core2Group item) =>
126+
string.Equals(
127+
item.DisplayName,
128+
parameters.AlternateFilters.Single().ComparisonValue,
129+
StringComparison.OrdinalIgnoreCase));
130+
}
131+
else
132+
{
133+
throw new NotSupportedException(SampleServiceResources.UnsupportedFilterAttributeGroup);
134+
}
135+
}
136+
137+
results =
138+
buffer
139+
.Select((Core2Group item) =>
140+
{
141+
Core2Group bufferItem =
142+
new Core2Group
143+
{
144+
DisplayName = item.DisplayName,
145+
ExternalIdentifier = item.ExternalIdentifier,
146+
Identifier = item.Identifier,
147+
Members = item.Members,
148+
Metadata = item.Metadata
149+
};
150+
151+
if (parameters?.ExcludedAttributePaths?.Any(
152+
(string excludedAttributes) =>
153+
excludedAttributes.Equals(AttributeNames.Members, StringComparison.OrdinalIgnoreCase))
154+
== true)
155+
{
156+
bufferItem.Members = null;
157+
}
158+
159+
return bufferItem;
160+
})
161+
.Select((Core2Group item) => item as Resource)
162+
.ToArray();
163+
164+
return Task.FromResult(results);
165+
}
166+
167+
public override Task<Resource> ReplaceAsync(Resource resource, string correlationIdentifier)
168+
{
169+
if (resource.Identifier == null)
170+
{
171+
throw new HttpResponseException(HttpStatusCode.BadRequest);
172+
}
173+
174+
Core2Group group = resource as Core2Group;
175+
176+
if (string.IsNullOrWhiteSpace(group.DisplayName))
177+
{
178+
throw new HttpResponseException(HttpStatusCode.BadRequest);
179+
}
180+
181+
IEnumerable<Core2Group> exisitingGroups = this.storage.Groups.Values;
182+
if
183+
(
184+
exisitingGroups.Any(
185+
(Core2Group exisitingUser) =>
186+
string.Equals(exisitingUser.DisplayName, group.DisplayName, StringComparison.Ordinal) &&
187+
!string.Equals(exisitingUser.Identifier, group.Identifier, StringComparison.OrdinalIgnoreCase))
188+
)
189+
{
190+
throw new HttpResponseException(HttpStatusCode.Conflict);
191+
}
192+
193+
if (!this.storage.Groups.TryGetValue(group.Identifier, out Core2Group _))
194+
{
195+
throw new HttpResponseException(HttpStatusCode.NotFound);
196+
}
197+
198+
this.storage.Groups[group.Identifier] = group;
199+
Resource result = group as Resource;
200+
return Task.FromResult(result);
201+
}
202+
203+
public override Task<Resource> RetrieveAsync(IResourceRetrievalParameters parameters, string correlationIdentifier)
204+
{
205+
if (parameters == null)
206+
{
207+
throw new ArgumentNullException(nameof(parameters));
208+
}
209+
210+
if (string.IsNullOrWhiteSpace(correlationIdentifier))
211+
{
212+
throw new ArgumentNullException(nameof(correlationIdentifier));
213+
}
214+
215+
if (string.IsNullOrEmpty(parameters?.ResourceIdentifier?.Identifier))
216+
{
217+
throw new ArgumentNullException(nameof(parameters));
218+
}
219+
220+
string identifier = parameters.ResourceIdentifier.Identifier;
221+
222+
if (this.storage.Groups.ContainsKey(identifier))
223+
{
224+
if (this.storage.Groups.TryGetValue(identifier, out Core2Group group))
225+
{
226+
Resource result = group as Resource;
227+
return Task.FromResult(result);
228+
}
229+
}
230+
231+
throw new HttpResponseException(HttpStatusCode.NotFound);
232+
}
233+
234+
public override Task UpdateAsync(IPatch patch, string correlationIdentifier)
235+
{
236+
if (null == patch)
237+
{
238+
throw new ArgumentNullException(nameof(patch));
239+
}
240+
241+
if (null == patch.ResourceIdentifier)
242+
{
243+
throw new ArgumentException(SampleServiceResources.ExceptionInvalidPatch);
244+
}
245+
246+
if (string.IsNullOrWhiteSpace(patch.ResourceIdentifier.Identifier))
247+
{
248+
throw new ArgumentException(SampleServiceResources.ExceptionInvalidPatch);
249+
}
250+
251+
if (null == patch.PatchRequest)
252+
{
253+
throw new ArgumentException(SampleServiceResources.ExceptionInvalidPatch);
254+
}
255+
256+
PatchRequest2 patchRequest =
257+
patch.PatchRequest as PatchRequest2;
258+
259+
if (null == patchRequest)
260+
{
261+
string unsupportedPatchTypeName = patch.GetType().FullName;
262+
throw new NotSupportedException(unsupportedPatchTypeName);
263+
}
264+
265+
if (this.storage.Groups.TryGetValue(patch.ResourceIdentifier.Identifier, out Core2Group group))
266+
{
267+
group.Apply(patchRequest);
268+
}
269+
else
270+
{
271+
throw new HttpResponseException(HttpStatusCode.NotFound);
272+
}
273+
274+
return Task.CompletedTask;
275+
}
276+
}
277+
}

0 commit comments

Comments
 (0)