Skip to content

Commit e065eea

Browse files
author
Tiago Brenck
committed
Create List and Delete TodoItem
1 parent 0b36d99 commit e065eea

File tree

13 files changed

+334
-19
lines changed

13 files changed

+334
-19
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Security.Claims;
5+
using System.Threading.Tasks;
6+
using WebApp_OpenIDConnect_DotNet.Models;
7+
8+
namespace WebApp_OpenIDConnect_DotNet.BLL
9+
{
10+
public interface ITodoItemService
11+
{
12+
Task<TodoItem> Create(string text, ClaimsPrincipal loggedUser);
13+
Task<IEnumerable<TodoItem>> List(bool showAll, ClaimsPrincipal loggedUser);
14+
Task<TodoItem> Get(int id, ClaimsPrincipal loggedUser);
15+
Task Delete(int id, ClaimsPrincipal loggedUser);
16+
}
17+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Identity.Web;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Security.Claims;
7+
using System.Threading.Tasks;
8+
using WebApp_OpenIDConnect_DotNet.DAL;
9+
using WebApp_OpenIDConnect_DotNet.Models;
10+
11+
namespace WebApp_OpenIDConnect_DotNet.BLL
12+
{
13+
public class TodoItemService : ITodoItemService
14+
{
15+
private readonly SampleDbContext sampleDbContext;
16+
public TodoItemService(SampleDbContext sampleDbContext)
17+
{
18+
this.sampleDbContext = sampleDbContext;
19+
}
20+
21+
public async Task<TodoItem> Create(string text, ClaimsPrincipal loggedUser)
22+
{
23+
TodoItem todoItem = new TodoItem
24+
{
25+
Text = text,
26+
UserName = loggedUser.Identity.Name,
27+
AssignedTo = loggedUser.GetObjectId(),
28+
TenantId = loggedUser.GetTenantId()
29+
};
30+
31+
sampleDbContext.TodoItems.Add(todoItem);
32+
await sampleDbContext.SaveChangesAsync();
33+
34+
return todoItem;
35+
}
36+
37+
public async Task Delete(int id, ClaimsPrincipal loggedUser)
38+
{
39+
var todoItem = await Get(id, loggedUser);
40+
if (todoItem != null)
41+
{
42+
sampleDbContext.TodoItems.Remove(todoItem);
43+
await sampleDbContext.SaveChangesAsync();
44+
}
45+
}
46+
47+
public async Task<TodoItem> Get(int id, ClaimsPrincipal loggedUser)
48+
{
49+
var tenantId = loggedUser.GetTenantId();
50+
var userIdentifier = loggedUser.GetObjectId();
51+
52+
return await sampleDbContext.TodoItems.SingleOrDefaultAsync(x =>
53+
x.Id == id
54+
&& x.TenantId == tenantId
55+
&& x.AssignedTo == userIdentifier);
56+
}
57+
58+
public async Task<IEnumerable<TodoItem>> List(bool showAll, ClaimsPrincipal loggedUser)
59+
{
60+
var tenantId = loggedUser.GetTenantId();
61+
var userIdentifier = loggedUser.GetObjectId();
62+
63+
var filteredResult = sampleDbContext.TodoItems.Where(x => x.TenantId == tenantId);
64+
65+
if (showAll)
66+
return await filteredResult.ToListAsync();
67+
else
68+
return await filteredResult.Where(x => x.AssignedTo == userIdentifier).ToListAsync();
69+
}
70+
}
71+
}

1-WebApp-OIDC/1-2-AnyOrg/Controllers/HomeController.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.AspNetCore.Authorization;
22
using Microsoft.AspNetCore.Mvc;
3+
using Microsoft.Identity.Web;
34
using System.Diagnostics;
45
using System.Linq;
56
using WebApp_OpenIDConnect_DotNet.DAL;
@@ -29,7 +30,12 @@ public IActionResult DeleteTenant(string id)
2930
dbContext.RemoveRange(tenants);
3031
dbContext.SaveChanges();
3132

32-
return RedirectToAction("Index");
33+
var signedUserTenant = User.GetTenantId();
34+
35+
if (id == signedUserTenant)
36+
return RedirectToAction("SignOut", "Account", new { area = "AzureAD" });
37+
else
38+
return RedirectToAction("Index");
3339
}
3440

3541
[AllowAnonymous]

1-WebApp-OIDC/1-2-AnyOrg/Controllers/OnboardingController.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ public OnboardingController(SampleDbContext dbContext, IOptions<AzureADOptions>
2525
}
2626

2727
[HttpGet]
28-
public ActionResult SignUp()
28+
public IActionResult SignUp()
2929
{
3030
return View();
3131
}
3232

3333
[HttpPost]
3434
[ValidateAntiForgeryToken]
35-
public ActionResult Onboard()
35+
public IActionResult Onboard()
3636
{
3737
// Generate a random value to identify the request
3838
string stateMarker = Guid.NewGuid().ToString();
@@ -60,11 +60,11 @@ public ActionResult Onboard()
6060
Uri.EscapeDataString(stateMarker));
6161

6262

63-
return new RedirectResult(authorizationRequest);
63+
return Redirect(authorizationRequest);
6464
}
6565

6666
// This is the redirect Uri for the admin consent authorization
67-
public async Task<ActionResult> ProcessCode(string tenant, string error, string error_description, string resource, string state)
67+
public async Task<IActionResult> ProcessCode(string tenant, string error, string error_description, string resource, string state)
6868
{
6969
if (error != null)
7070
{
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Authorization;
6+
using Microsoft.AspNetCore.Mvc;
7+
using Microsoft.Identity.Web;
8+
using WebApp_OpenIDConnect_DotNet.BLL;
9+
using WebApp_OpenIDConnect_DotNet.Models;
10+
11+
namespace WebApp_OpenIDConnect_DotNet.Controllers
12+
{
13+
[Authorize]
14+
public class TodoListController : Controller
15+
{
16+
private readonly ITodoItemService _todoItemService;
17+
public TodoListController(ITodoItemService todoItemService)
18+
{
19+
_todoItemService = todoItemService;
20+
}
21+
22+
public async Task<IActionResult> Index(bool showAllFilter)
23+
{
24+
@TempData["ShowAllFilter"] = showAllFilter;
25+
26+
var items = await _todoItemService.List(showAllFilter, User);
27+
return View(items);
28+
}
29+
30+
[HttpGet]
31+
public IActionResult Create()
32+
{
33+
var model = new TodoItem()
34+
{
35+
AssignedTo = User.GetObjectId(),
36+
TenantId = User.GetTenantId(),
37+
UserName = User.Identity.Name
38+
};
39+
40+
return View(model);
41+
}
42+
43+
[HttpPost]
44+
public async Task<IActionResult> Create(TodoItem model)
45+
{
46+
await _todoItemService.Create(model.Text, User);
47+
return RedirectToAction("Index");
48+
}
49+
50+
[HttpGet]
51+
public async Task<IActionResult> Delete(int id)
52+
{
53+
await _todoItemService.Delete(id, User);
54+
return RedirectToAction("Index");
55+
}
56+
}
57+
}

1-WebApp-OIDC/1-2-AnyOrg/DAL/SampleDbContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ public class SampleDbContext : DbContext
1212
public SampleDbContext(DbContextOptions<SampleDbContext> options) : base(options) { }
1313

1414
public DbSet<AuthorizedTenant> AuthorizedTenants { get; set; }
15+
public DbSet<TodoItem> TodoItems { get; set; }
1516
}
1617
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel.DataAnnotations;
4+
using System.ComponentModel.DataAnnotations.Schema;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
8+
namespace WebApp_OpenIDConnect_DotNet.Models
9+
{
10+
public class TodoItem
11+
{
12+
[Key]
13+
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
14+
public int Id { get; set; }
15+
public string Text { get; set; }
16+
public string UserName { get; set; }
17+
public string AssignedTo { get; set; }
18+
public string TenantId { get; set; }
19+
}
20+
}

1-WebApp-OIDC/1-2-AnyOrg/Startup.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Collections.Generic;
1818
using System.Linq;
1919
using System.Threading.Tasks;
20+
using WebApp_OpenIDConnect_DotNet.BLL;
2021
using WebApp_OpenIDConnect_DotNet.DAL;
2122
using WebApp_OpenIDConnect_DotNet.Utils;
2223

@@ -43,14 +44,16 @@ public void ConfigureServices(IServiceCollection services)
4344

4445
services.AddOptions();
4546

46-
services.AddDbContext<SampleDbContext>(options => options.UseInMemoryDatabase(databaseName: "MultiTenantOnboarding"));
47+
//services.AddDbContext<SampleDbContext>(options => options.UseInMemoryDatabase(databaseName: "MultiTenantOnboarding"));
48+
services.AddDbContext<SampleDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SampleDbConnStr")));
49+
50+
services.AddScoped<ITodoItemService, TodoItemService>();
4751

4852
// Sign-in users with the Microsoft identity platform
4953
services.AddMicrosoftIdentityPlatformAuthentication(Configuration);
50-
54+
5155
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
5256
{
53-
//options.TokenValidationParameters = BuildTokenValidationParameters(options);
5457
options.Events.OnTokenValidated = async context =>
5558
{
5659
string tenantId = context.SecurityToken.Claims.FirstOrDefault(x => x.Type == "tid" || x.Type == "http://schemas.microsoft.com/identity/claims/tenantid")?.Value;
@@ -91,6 +94,13 @@ public void ConfigureServices(IServiceCollection services)
9194
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
9295
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
9396
{
97+
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
98+
{
99+
var context = serviceScope.ServiceProvider.GetRequiredService<SampleDbContext>();
100+
//context.Database.EnsureDeleted();
101+
context.Database.EnsureCreated();
102+
}
103+
94104
if (env.IsDevelopment())
95105
{
96106
app.UseDeveloperExceptionPage();
Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
@model IEnumerable<AuthorizedTenant>
1+
@using System.Security.Principal
2+
@using Microsoft.Identity.Web
3+
@model IEnumerable<AuthorizedTenant>
24
@{
35
ViewData["Title"] = "Home Page";
46
}
@@ -9,12 +11,15 @@
911
<p>
1012
This sample shows how to build a .NET Core MVC Web app that uses OpenID Connect to sign in users. Users can use work and school accounts from any company or organization that has integrated with Azure Active Directory. It leverages the ASP.NET Core OpenID Connect middleware.
1113
</p>
12-
<img src="https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/raw/master/1-WebApp-OIDC/1-2-AnyOrg/ReadmeFiles/sign-in.png"/>
14+
<img src="https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/raw/master/1-WebApp-OIDC/1-2-AnyOrg/ReadmeFiles/sign-in.png" />
1315
<hr />
1416

1517
<h2>Authorized Tenants</h2>
1618
<p>
17-
These are the authorized tenants. If you want to repeat the onboarding process, deleted the desired tenants and <b>sign-out.</b>
19+
These are the authorized tenants on the database. If you want to repeat the onboarding process, offboard the desired tenant from this list.
20+
</p>
21+
<p>
22+
Offboarding the signed user's tenant, will trigger a <b>sign-out.</b>
1823
</p>
1924

2025
<table class="table">
@@ -25,12 +30,18 @@
2530
</tr>
2631
</thead>
2732
<tbody>
28-
@foreach (var tenant in Model)
29-
{
30-
<tr>
31-
<td>@tenant.TenantId</td>
32-
<td><a asp-controller="Home" asp-action="DeleteTenant" asp-route-id=@tenant.TenantId class="btn btn-danger">Delete</a></td>
33-
</tr>
34-
}
33+
@foreach (var tenant in Model)
34+
{
35+
<tr>
36+
<td>
37+
<span>@tenant.TenantId</span>
38+
@if (tenant.TenantId == User.GetTenantId())
39+
{
40+
<span class="label label-primary">your tenant</span>
41+
}
42+
</td>
43+
<td><a asp-controller="Home" asp-action="DeleteTenant" asp-route-id=@tenant.TenantId class="btn btn-danger">Offboard</a></td>
44+
</tr>
45+
}
3546
</tbody>
3647
</table>

1-WebApp-OIDC/1-2-AnyOrg/Views/Shared/_Layout.cshtml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<div class="navbar-collapse collapse">
3232
<ul class="nav navbar-nav">
3333
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
34+
<li><a asp-area="" asp-controller="TodoList" asp-action="Index">Todo List</a></li>
3435
</ul>
3536
<partial name="_LoginPartial" />
3637
</div>

0 commit comments

Comments
 (0)