// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.Text.Json; using Regorus.Internal; #nullable enable namespace Regorus { /// /// Represents a compiled Regorus policy that can be evaluated efficiently. /// This class wraps a pre-compiled policy that can be evaluated multiple times /// with different inputs without recompilation overhead. /// /// This class manages unmanaged resources and should not be copied or cloned. /// Each instance represents a unique native policy object. /// /// Thread Safety: This class is thread-safe for all operations. Multiple threads /// can safely call EvalWithInput() concurrently. Dispose() blocks new calls, waits /// briefly, and defers the native release to the last in-flight caller if needed. /// No external synchronization is required. /// public unsafe sealed class CompiledPolicy : SafeHandleWrapper { internal CompiledPolicy(RegorusCompiledPolicyHandle handle) : base(handle, nameof(CompiledPolicy)) { } /// /// Evaluates the compiled policy with the given input. /// For target policies, evaluates the target's effect rule. /// For regular policies, evaluates the originally compiled rule. /// /// JSON encoded input data (resource) to validate against the policy /// The evaluation result as JSON string /// Thrown when policy evaluation fails /// Thrown when the policy has been disposed public string? EvalWithInput(string inputJson) { return Internal.Utf8Marshaller.WithUtf8(inputJson, inputPtr => { return UseHandle(policyPtr => { unsafe { return CheckAndDropResult(Internal.API.regorus_compiled_policy_eval_with_input((Internal.RegorusCompiledPolicy*)policyPtr, (byte*)inputPtr)); } }); }); } /// /// Gets information about the compiled policy including metadata about modules, /// target configuration, and resource types. /// /// Policy information containing module IDs, target name, applicable resource types, entry point rule, and parameters /// Thrown when getting policy info fails /// Thrown when the policy has been disposed public PolicyInfo GetPolicyInfo() { var jsonResult = UseHandle(policyPtr => { unsafe { return CheckAndDropResult(Internal.API.regorus_compiled_policy_get_policy_info((Internal.RegorusCompiledPolicy*)policyPtr)); } }); if (string.IsNullOrEmpty(jsonResult)) { throw new Exception("Failed to get policy info: empty response"); } try { var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; return JsonSerializer.Deserialize(jsonResult!, options) ?? throw new Exception("Failed to deserialize policy info"); } catch (JsonException ex) { throw new Exception($"Failed to parse policy info JSON: {ex.Message}", ex); } } private string? CheckAndDropResult(Internal.RegorusResult result) { return Internal.ResultHelpers.GetStringResult(result); } } }