Skip to content

Instantly share code, notes, and snippets.

View martyncoup's full-sized avatar
🎯
APIs!

Martyn Coupland martyncoup

🎯
APIs!
View GitHub Profile
@martyncoup
martyncoup / Program.cs
Last active November 19, 2024 20:45
Validate plus address against a root address
using System;
public static class Program
{
public static bool IsPlusAddressUsed(string plus, string root)
{
var parts = plus.Split('@');
var formattedEmail = $"{parts[0].Split('+')[0]}@{parts[1]}";
return formattedEmail == root;
}
public class CustomDateTimeConverter : DateTimeConverterBase
{
private readonly string dateFormat = null;
private readonly DateTimeConverterBase innerConverter = null;
public CustomDateTimeConverter()
: this(dateFormat: null)
{
}
public static class Helper
{
private static readonly string[] CUSTOM_DATE_FORMATS = new string[]
{
"yyyyMMddTHHmmssZ",
"yyyyMMddTHHmmZ",
"yyyyMMddTHHmmss",
"yyyyMMddTHHmm",
"yyyyMMddHHmmss",
"yyyyMMddHHmm",
public class DateTimeModelBinder : IModelBinder
{
public static readonly Type[] SupportedTypes = [typeof(DateTime), typeof(DateTime?)];
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
@martyncoup
martyncoup / Program.cs
Created April 22, 2024 12:37
Add management of data protection keys
// Add data protection keys
builder.Services.AddDataProtection()
.SetApplicationName("YourAppName")
.SetDefaultKeyLifetime(TimeSpan.FromDays(30))
.PersistKeysToAzureBlobStorage(new Uri(builder.Configuration["DataProtectionKeysUri"]), new DefaultAzureCredential())
.ProtectKeysWithAzureKeyVault(new Uri(builder.Configuration["DataProtectionVaultIdentifierUri"]), new DefaultAzureCredential());
// Removed for brevity
builder.Services.AddAuthentication(...);
// Configure load balancer headers for MS Identity
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, o =>
{
o.Events = new OpenIdConnectEvents
{
// Override the redirect URI
OnRedirectToIdentityProvider = (context) =>
@martyncoup
martyncoup / CallWebApi.cs
Created April 12, 2021 13:09
Call Azure API through downstream web API service
var response = await _downstreamWebApi.CallWebApiForAppAsync(
"AzureApi",
options =>
{
options.BaseUrl = "https://management.azure.com";
options.HttpMethod = HttpMethod.Get;
options.RelativePath = "subscriptions/<sub id>/resourcegroups?api-version=2020-09-01";
options.Scopes = "https://management.azure.com//.default";
options.Tenant = "<tenant id>";
});
@martyncoup
martyncoup / DownstreamWebApi.cs
Created April 12, 2021 13:04
Enable token acquisition for downstream APIs
services.AddMicrosoftIdentityWebApiAuthentication(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDownstreamWebApi("Azure", Configuration.GetSection("AzureApi"))
.AddInMemoryTokenCaches();
@martyncoup
martyncoup / UserAndGroupRoles.cs
Created April 6, 2021 12:20
Gets users and group based role assignment
// Get user role assignments
var oid = context.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
var userRoles = dbContext.RoleMaps.Where(w => w.ObjectId == oid).Join(dbContext.Roles, map => map.RoleId,
role => role.Id, (map, role) => new {RoleName = role.Name}).ToList();
// Get group role assignments
var groupClaims = context.Principal.Claims.Where(w => w.Type == "groups").Select(s => s.Value).ToList();
var groupRoles = dbContext.RoleMaps.Where(w => groupClaims.Contains(w.ObjectId)).Join(dbContext.Roles, map => map.RoleId,
role => role.Id, (map, role) => new { RoleName = role.Name }).ToList();
@martyncoup
martyncoup / GroupRoleAssignment.cs
Created April 6, 2021 12:17
Checks for group claims in the list of role access
// Get group role assignments
var groupClaims = context.Principal.Claims.Where(w => w.Type == "groups").Select(s => s.Value).ToList();
var groupRoles = dbContext.RoleMaps.Where(w => groupClaims.Contains(w.ObjectId)).Join(dbContext.Roles, map => map.RoleId,
role => role.Id, (map, role) => new { RoleName = role.Name }).ToList();