Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…e-extension into dajusto/remove-potentially-sensitive-logs
  • Loading branch information
davidmrdavid committed Jul 9, 2024
2 parents bac3b33 + 08c385b commit 2af6b47
Show file tree
Hide file tree
Showing 16 changed files with 523 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.DurableTask.ContextImplementations;
using Microsoft.Azure.WebJobs.Extensions.DurableTask.Options;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using TodoApi.Models;

namespace TodoApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TodoController : Controller
{
private readonly TodoContext _context;
private readonly IDurableClient _client;

public TodoController(TodoContext context, IDurableClientFactory clientFactory, IConfiguration configuration)
{
_context = context;

if (_context.TodoItems.Count() == 0)
{
_context.TodoItems.Add(new TodoItem { Name = "Item1" });
_context.SaveChanges();
}

_client = clientFactory.CreateClient(new DurableClientOptions
{
ConnectionName = configuration["MyStorage"],
TaskHub = configuration["TaskHub"]
});
}

// GET: api/Todo
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItem()
{
return await _context.TodoItems.ToListAsync();
}

// GET: api/Todo/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);

if (todoItem == null)
{
return NotFound();
}

return todoItem;
}

// PUT: api/Todo/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
if (id != todoItem.Id)
{
return BadRequest();
}

_context.Entry(todoItem).State = EntityState.Modified;

try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoItemExists(id))
{
return NotFound();
}
else
{
throw;
}
}

return NoContent();
}

// POST: api/Todo
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();

string instanceId = await _client.StartNewAsync<string>("SetReminder", todoItem.Name);

return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
}

// DELETE: api/Todo/5
[HttpDelete("{id}")]
public async Task<ActionResult<TodoItem>> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}

_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();

return todoItem;
}

private bool TodoItemExists(long id)
{
return _context.TodoItems.Any(e => e.Id == id);
}
}
}
22 changes: 22 additions & 0 deletions samples/durable-client-managed-identity/aspnetcore-app/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

namespace TodoApi
{
public class Program
{

static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
37 changes: 37 additions & 0 deletions samples/durable-client-managed-identity/aspnetcore-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ASP.NET Core API To Do List Sample with Identity-Based Connection

This example is adapted from the [To Do List sample](https://github.com/Azure-Samples/dotnet-core-api) in the Azure-Samples repository. It demonstrates an ASP.NET Core application with an injected Durable Client and identity-based connections. In this sample, the Durable Client is configured to use a storage connection with a custom name, `MyStorage`, and is set up to utilize a client secret for authentication.


## To make the sample run, you need to:

1. Create an identity for your Function App in the Azure portal.

2. Grant the following Role-Based Access Control (RBAC) permissions to the identity:
- Storage Queue Data Contributor
- Storage Blob Data Contributor
- Storage Table Data Contributor

3. Link your storage account to your Function App by adding either of these two details to your configuration, which is appsettings.json file in this sample .
- accountName
- blobServiceUri, queueServiceUri and tableServiceUri

4. Add the required identity information to your Functions App configuration, which is appsettings.json file in this sample.
- system-assigned identity: nothing needs to be provided.
- user-assigned identity:
- credential: managedidentity
- clientId
- client secret application:
- clientId
- ClientSecret
- tenantId


## Notes
- The storage connection information must be provided in the format specified in the appsettings.json file.
- If your storage information is saved in a custom-named JSON file, be sure to add it to your configuration as shown below.
```csharp
this.Configuration = new ConfigurationBuilder()
.AddJsonFile("myjson.json")
.Build();
```
74 changes: 74 additions & 0 deletions samples/durable-client-managed-identity/aspnetcore-app/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using TodoApi.Models;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;

namespace TodoApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// AddDurableClientFactory() registers IDurableClientFactory as a service so the application
// can consume it and and call the Durable Client APIs
services.AddDurableClientFactory();

services.AddControllers();

// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});

services.AddDbContext<TodoContext>(options => options.UseInMemoryDatabase("TodoList"));
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();

// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

//app.UseHttpsRedirection();

app.UseDefaultFiles();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="EntityFramework" Version="6.4.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.13.5" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30503.244
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToDoList", "ToDoList.csproj", "{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D75105D4-B93A-4A9B-B12E-E8EF0F7E6223}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E7920E27-E4F7-47B7-B1B9-01F8645883CA}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"TaskHub": "MyTestHub",
"MyStorage": {
"accountName": "YourStorageAccountName",
"clientId": "<your client id here>",
"clientsecret": "<your client secret here>",
"tenantId": "<your tenant id here>"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.DurableTask.ContextImplementations;
using Microsoft.Azure.WebJobs.Extensions.DurableTask.Options;
using Microsoft.Extensions.Configuration;

namespace DurableClientSampleFunctionApp
{
public class ClientFunction
{
private readonly IDurableClient _client;

public ClientFunction(IDurableClientFactory clientFactory, IConfiguration configuration)
{
_client = clientFactory.CreateClient(new DurableClientOptions
{
ConnectionName = "ClientStorage",
TaskHub = configuration["TaskHub"]
});
}

[FunctionName("CallHelloSequence")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");

string instanceId = await _client.StartNewAsync("E1_HelloSequence");

DurableOrchestrationStatus status = await _client.GetStatusAsync(instanceId);

while (status.RuntimeStatus == OrchestrationRuntimeStatus.Pending ||
status.RuntimeStatus == OrchestrationRuntimeStatus.Running ||
status.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew)
{
await Task.Delay(10000);
status = await _client.GetStatusAsync(instanceId);
}

return new ObjectResult(status);
}
}
}
Loading

0 comments on commit 2af6b47

Please sign in to comment.