using Hangfire.Common; using Hangfire.Server; using Strata.CoreLib.Claims; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Security.Claims; using System.Threading; namespace Strata.RxNorm.Biz.Hangfire { /// /// Captures Job parameters as Claims on the ThreadPrincipal running the job /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method)] public class CaptureJobParameterAttribute : JobFilterAttribute, IServerFilter { public int DatabaseGuidArgumentPosition { get; set; } = -1; public int StrataIdArgumentPosition { get; set; } = -1; // server filters public void OnPerforming(PerformingContext filterContext) { var claims = new List(); var args = filterContext.BackgroundJob.Job.Args.ToArray(); if (StrataIdArgumentPosition >= 0) { var strataIdValue = string.Format(CultureInfo.CurrentCulture, $"{{{StrataIdArgumentPosition}}}", args); if (int.TryParse(strataIdValue, out var strataId)) { claims.Add(new Claim(StrataClaims.StrataId, strataId.ToString())); } } if (DatabaseGuidArgumentPosition >= 0) { var databaseGuidValue = string.Format(CultureInfo.CurrentCulture, $"{{{DatabaseGuidArgumentPosition}}}", args); if (Guid.TryParse(databaseGuidValue, out var databaseGuid)) { claims.Add(new Claim(StrataClaims.DatabaseGuid, databaseGuid.ToString())); } } if (claims.Count == 0) { return; } var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "hangfire_impersonation")); Thread.CurrentPrincipal = principal; } public void OnPerformed(PerformedContext filterContext) { Thread.CurrentPrincipal = null; } } }