Skip to content

Commit 7289a0d

Browse files
committed
Added BASHER logic to Service controller and made some refactoring
1 parent 2599ef8 commit 7289a0d

File tree

15 files changed

+154
-36
lines changed

15 files changed

+154
-36
lines changed

4-WebApp-your-API/4-1-MyOrg/AppCreationScripts-withCert/sample.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,19 @@
9494
"SampleSubPath": "4-WebApp-Your-API\\4-1-MyOrg",
9595
"ProjectDirectory": "\\TodoListService"
9696
},
97-
"AppScopes": [ "ToDoList.Read", "ToDoList.Write" ]
98-
97+
"Scopes": [ "ToDoList.Read", "ToDoList.ReadWrite" ]
98+
//"AppRoles": [
99+
// {
100+
// "Types": [ "Application" ],
101+
// "Name": "ToDoList.Read.All",
102+
// "Description": "Application can only read ToDo list"
103+
// },
104+
// {
105+
// "Types": [ "Application" ],
106+
// "Name": "ToDoList.ReadWrite.All",
107+
// "Description": "Application can read and write into ToDo list"
108+
// }
109+
//]
99110
},
100111
{
101112
"Id": "client",
@@ -114,6 +125,8 @@
114125
],
115126
"Certificate": "the certificate will be named by application name",
116127
"ManualSteps": [],
128+
"EnableAccessTokenIssuance": "true",
129+
"EnableIdTokenIssuance": "false",
117130
"Sample": {
118131
"SampleSubPath": "4-WebApp-Your-API\\4-1-MyOrg",
119132
"ProjectDirectory": "\\Client"

4-WebApp-your-API/4-1-MyOrg/AppCreationScripts/sample.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,19 @@
9494
"SampleSubPath": "4-WebApp-Your-API\\4-1-MyOrg",
9595
"ProjectDirectory": "\\TodoListService"
9696
},
97-
"Scopes": [ "ToDoList.Read", "ToDoList.Write" ]
97+
"Scopes": [ "ToDoList.Read", "ToDoList.ReadWrite" ]
98+
//"AppRoles": [
99+
// {
100+
// "Types": [ "Application" ],
101+
// "Name": "ToDoList.Read.All",
102+
// "Description": "Application can only read ToDo list"
103+
// },
104+
// {
105+
// "Types": [ "Application" ],
106+
// "Name": "ToDoList.ReadWrite.All",
107+
// "Description": "Application can read and write into ToDo list"
108+
// }
109+
//]
98110
},
99111
{
100112
"Id": "client",
@@ -112,6 +124,8 @@
112124
}
113125
],
114126
"ManualSteps": [],
127+
"EnableAccessTokenIssuance": "true",
128+
"EnableIdTokenIssuance": "false",
115129
"Sample": {
116130
"SampleSubPath": "4-WebApp-Your-API\\4-1-MyOrg",
117131
"ProjectDirectory": "\\Client"

4-WebApp-your-API/4-1-MyOrg/Client/Controllers/TodoListController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
using Microsoft.AspNetCore.Mvc;
33
using Microsoft.Identity.Web;
44
using System.Threading.Tasks;
5+
using TodoListClient.Models;
56
using TodoListClient.Services;
6-
using TodoListService.Models;
77

88
namespace TodoListClient.Controllers
99
{

4-WebApp-your-API/4-1-MyOrg/Client/Infrastructure/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ public static class Constants
44
{
55
public const string ScopeUserImpersonation = "user_impersonation";
66
public const string BearerAuthorizationScheme = "Bearer";
7+
public const string ScopeClaimType = "http://schemas.microsoft.com/identity/claims/scope";
78
}
89
}

4-WebApp-your-API/4-1-MyOrg/TodoListService/Models/TodoItem.cs renamed to 4-WebApp-your-API/4-1-MyOrg/Client/Models/TodoItem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace TodoListService.Models
1+
namespace TodoListClient.Models
22
{
33
public class Todo
44
{

4-WebApp-your-API/4-1-MyOrg/Client/Services/ITodoListService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2424

2525
using System.Collections.Generic;
2626
using System.Threading.Tasks;
27-
using TodoListService.Models;
27+
using TodoListClient.Models;
2828

2929
namespace TodoListClient.Services
3030
{

4-WebApp-your-API/4-1-MyOrg/Client/Services/TodoListService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
using System.Net.Http.Headers;
1313
using System.Text;
1414
using System.Threading.Tasks;
15-
using TodoListService.Models;
15+
using TodoListClient.Models;
1616

1717
namespace TodoListClient.Services
1818
{

4-WebApp-your-API/4-1-MyOrg/Client/TodoListClient.csproj

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,8 @@
1818
</ItemGroup>
1919

2020
<ItemGroup>
21-
<Compile Include="..\TodoListService\Models\TodoItem.cs" Link="Models\TodoItem.cs" />
22-
</ItemGroup>
23-
24-
<ItemGroup>
25-
<PackageReference Include="Microsoft.Identity.Web" Version="1.24.0" />
26-
<PackageReference Include="Microsoft.Identity.Web.UI" Version="1.24.0" />
21+
<PackageReference Include="Microsoft.Identity.Web" Version="1.25.0" />
22+
<PackageReference Include="Microsoft.Identity.Web.UI" Version="1.25.0" />
2723
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
2824
</ItemGroup>
2925

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Create.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListService.Models.Todo
1+
@model TodoListClient.Models.Todo
22
@{
33
ViewData["Title"] = "Create";
44
}

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Delete.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListService.Models.Todo
1+
@model TodoListClient.Models.Todo
22

33
@{
44
ViewData["Title"] = "Delete";

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Details.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListService.Models.Todo
1+
@model TodoListClient.Models.Todo
22

33
@{
44
ViewData["Title"] = "Details";

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Edit.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model TodoListService.Models.Todo
1+
@model TodoListClient.Models.Todo
22
@{
33
ViewData["Title"] = "Edit";
44
}

4-WebApp-your-API/4-1-MyOrg/Client/Views/TodoList/Index.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@model IEnumerable<TodoListService.Models.Todo>
1+
@model IEnumerable<TodoListClient.Models.Todo>
22

33
@{
44
ViewData["Title"] = "Index";

4-WebApp-your-API/4-1-MyOrg/TodoListService/Controllers/TodoListController.cs

Lines changed: 107 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
using Microsoft.AspNetCore.Http;
66
using Microsoft.AspNetCore.Mvc;
77
using Microsoft.Identity.Web.Resource;
8+
using System;
89
using System.Collections.Generic;
910
using System.Linq;
10-
using TodoListService.Models;
11+
using System.Security.Claims;
12+
using TodoListClient.Models;
13+
using WebApp_OpenIDConnect_DotNet.Infrastructure;
1114

1215
namespace TodoListService.Controllers
1316
{
@@ -29,64 +32,151 @@ public TodoListController(IHttpContextAccessor contextAccessor)
2932
{
3033
TodoStore.Add(1, new Todo() { Id = 1, Owner = $"{_contextAccessor.HttpContext.User.Identity.Name}", Title = "Pick up groceries" });
3134
TodoStore.Add(2, new Todo() { Id = 2, Owner = $"{_contextAccessor.HttpContext.User.Identity.Name}", Title = "Finish invoice report" });
35+
TodoStore.Add(3, new Todo() { Id = 3, Owner = "Other User", Title = "Rent a car" });
36+
TodoStore.Add(4, new Todo() { Id = 4, Owner = "Other User", Title = "Get vaccinated" });
3237
}
3338
}
3439

3540
// GET: api/values
3641
[HttpGet]
37-
[RequiredScope(new string[] { "ToDoList.Read", "ToDoList.Write" })]
42+
[RequiredScopeOrAppPermission(
43+
AcceptedScope = new string[] { "ToDoList.Read", "ToDoList.ReadWrite" },
44+
AcceptedAppPermission = new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" }
45+
)]
3846
public IEnumerable<Todo> Get()
3947
{
40-
string owner = User.Identity.Name;
41-
return TodoStore.Values.Where(x => x.Owner == owner);
48+
if (IsInScopes(new string[] { "ToDoList.Read", "ToDoList.ReadWrite" }))
49+
{
50+
return TodoStore.Values.Where(x => x.Owner == User.Identity.Name);
51+
}
52+
else if (IsInPermissions(new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" }))
53+
{
54+
return TodoStore.Values;
55+
}
56+
57+
throw new ApplicationException("It's impossible for you to be in this state in a normal situation.");
4258
}
4359

4460
// GET: api/values
4561
[HttpGet("{id}", Name = "Get")]
46-
[RequiredScope(new string[] { "ToDoList.Read", "ToDoList.Write" })]
62+
[RequiredScopeOrAppPermission(
63+
AcceptedScope = new string[] { "ToDoList.Read", "ToDoList.ReadWrite" },
64+
AcceptedAppPermission = new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" })]
4765
public Todo Get(int id)
4866
{
49-
return TodoStore.Values.FirstOrDefault(t => t.Id == id);
67+
//if it only has delegated permissions
68+
//then it will be t.id==id && x.Owner == owner
69+
//if it has app permissions the it will return t.id==id
70+
71+
if (IsInScopes(new string[] { "ToDoList.Read", "ToDoList.ReadWrite" }))
72+
{
73+
return TodoStore.Values.FirstOrDefault(t => t.Id == id && t.Owner == User.Identity.Name);
74+
}
75+
else if (IsInPermissions(new string[] { "ToDoList.Read.All", "ToDoList.ReadWrite.All" }))
76+
{
77+
return TodoStore.Values.FirstOrDefault(t => t.Id == id);
78+
}
79+
80+
throw new ApplicationException("It's impossible for you to be in this state. STINKY HACKER");
5081
}
5182

5283
[HttpDelete("{id}")]
53-
[RequiredScope("ToDoList.Write")]
84+
[RequiredScopeOrAppPermission(
85+
AcceptedScope = new string[] { "ToDoList.ReadWrite" },
86+
AcceptedAppPermission = new string[] { "ToDoList.ReadWrite.All" })]
5487
public void Delete(int id)
5588
{
56-
TodoStore.Remove(id);
89+
90+
if (
91+
(
92+
93+
IsInScopes(new string[] { "ToDoList.ReadWrite" }) && TodoStore.Values.Any(x => x.Id == id && x.Owner == User.Identity.Name))
94+
95+
||
96+
97+
IsInPermissions(new string[] { "ToDoList.ReadWrite.All" })
98+
)
99+
{
100+
TodoStore.Remove(id);
101+
}
102+
103+
else
104+
{
105+
throw new ApplicationException("No idea how you've got here");
106+
}
57107
}
58108

59109
// POST api/values
60110
[HttpPost]
61-
[RequiredScope("ToDoList.Write")]
111+
[RequiredScopeOrAppPermission(
112+
AcceptedScope = new string[] { "ToDoList.ReadWrite" },
113+
AcceptedAppPermission = new string[] { "ToDoList.ReadWrite.All" })]
62114
public IActionResult Post([FromBody] Todo todo)
63115
{
116+
var owner = HttpContext.User.Identity.Name;
117+
118+
if (IsInPermissions(new string[] { "ToDoList.ReadWrite.All" }))
119+
{
120+
//with such a permission any owner name is accepted from UI
121+
owner = todo.Owner;
122+
}
123+
else
124+
{
125+
throw new ApplicationException("Somehow you've sneaked in. Impossible... Just a bug in Matrix...");
126+
}
127+
64128
int id = TodoStore.Values.OrderByDescending(x => x.Id).FirstOrDefault().Id + 1;
65-
Todo todonew = new Todo() { Id = id, Owner = HttpContext.User.Identity.Name, Title = todo.Title };
129+
Todo todonew = new Todo() { Id = id, Owner = owner, Title = todo.Title };
66130
TodoStore.Add(id, todonew);
67131

68132
return Ok(todo);
69133
}
70134

71135
// PATCH api/values
72136
[HttpPatch("{id}")]
73-
[RequiredScope("ToDoList.Write")]
137+
[RequiredScopeOrAppPermission(
138+
AcceptedScope = new string[] { "ToDoList.ReadWrite" },
139+
AcceptedAppPermission = new string[] { "ToDoList.ReadWrite.All" })]
74140
public IActionResult Patch(int id, [FromBody] Todo todo)
75141
{
76-
if (id != todo.Id)
142+
if (id != todo.Id || !TodoStore.Values.Any(x => x.Id == id))
77143
{
78144
return NotFound();
79145
}
80146

81-
if (TodoStore.Values.FirstOrDefault(x => x.Id == id) == null)
147+
if (
148+
IsInScopes(new string[] { "ToDoList.ReadWrite" })
149+
&& TodoStore.Values.Any(x => x.Id == id && x.Owner == User.Identity.Name)
150+
&& todo.Owner == User.Identity.Name
151+
152+
||
153+
154+
IsInPermissions(new string[] { "ToDoList.ReadWrite.All" })
155+
156+
)
82157
{
83-
return NotFound();
158+
TodoStore.Remove(id);
159+
TodoStore.Add(id, todo);
160+
161+
return Ok(todo);
84162
}
85163

86-
TodoStore.Remove(id);
87-
TodoStore.Add(id, todo);
164+
throw new ApplicationException("You have insufficient permissions to run this patch operation.");
88165

89-
return Ok(todo);
166+
}
167+
168+
//check if the permission is inside claims
169+
private bool IsInPermissions(string[] permissionsNames)
170+
{
171+
return User.Claims.Where(c => c.Type.Equals(ClaimTypes.Role)).FirstOrDefault()
172+
.Value.Split(' ').Any(v => permissionsNames.Any(p => p.Equals(v)));
173+
}
174+
175+
//check if the scope is inside claims
176+
private bool IsInScopes(string[] scopesNames)
177+
{
178+
return User.Claims.Where(c => c.Type.Equals(Constants.ScopeClaimType)).FirstOrDefault()
179+
.Value.Split(' ').Any(v => scopesNames.Any(s => s.Equals(v)));
90180
}
91181
}
92182
}

4-WebApp-your-API/4-1-MyOrg/TodoListService/TodoListService.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Microsoft.Identity.Web" Version="1.24.0" />
10+
<PackageReference Include="Microsoft.Identity.Web" Version="1.25.0" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\Client\TodoListClient.csproj" />
1115
</ItemGroup>
1216

1317
</Project>

0 commit comments

Comments
 (0)