private SecurableResource createSecurableResource(SecurableResourceType type, Dictionary <string, byte[]> rawPropertyValues, JsonSerializerOptions options)
        {
            SecurableResource readResource = type switch
            {
                SecurableResourceType.Tenant => new Jibberwock.DataModels.Tenants.Tenant(),
                SecurableResourceType.ApiKey => new Jibberwock.DataModels.Tenants.ApiKey(),
                SecurableResourceType.Product => new Jibberwock.DataModels.Products.Product(),
                SecurableResourceType.Service => new Jibberwock.DataModels.Core.Service(),
                SecurableResourceType.Allert_AlertDefinition => new Jibberwock.DataModels.Allert.AlertDefinition(),
                SecurableResourceType.Allert_AlertDefinitionGroup => new Jibberwock.DataModels.Allert.AlertDefinitionGroup(),
                _ => throw new JsonException($"Unable to create a SecurableResource from type {type}."),
            };

            var clrType    = readResource.GetType();
            var properties = clrType.GetProperties();

            foreach (var pi in properties)
            {
                var    expectedPropertyName = options.PropertyNamingPolicy.ConvertName(pi.Name);
                byte[] rawPropertyValue;

                // If we're using a case-insensitive property value, we have to iterate the dictionary manually.
                // Otherwise, we can take a shortcut via a key lookup.
                if (options.PropertyNameCaseInsensitive)
                {
                    var kvp = rawPropertyValues.FirstOrDefault(kvp => string.Equals(kvp.Key, expectedPropertyName, StringComparison.OrdinalIgnoreCase));

                    if (kvp.Value == null)
                    {
                        continue;
                    }

                    rawPropertyValue = kvp.Value;
                }
                else
                {
                    if (!rawPropertyValues.TryGetValue(expectedPropertyName, out rawPropertyValue))
                    {
                        continue;
                    }
                }

                object deserialisedValue;
                if (pi.PropertyType == typeof(string) && rawPropertyValue.Length > 0)
                {
                    deserialisedValue = Encoding.UTF8.GetString(rawPropertyValue);
                }
                else
                {
                    deserialisedValue = JsonSerializer.Deserialize(rawPropertyValue.AsSpan(), pi.PropertyType, options);
                }

                pi.SetValue(readResource, deserialisedValue);
            }

            return(readResource);
        }
        public SecurableResourcePermissionCheck(long resourceId, SecurableResourceType resourceType, Permission permission)
            : base(
                GetColumnMetadata <long>("Securable_Resource_ID"),
                GetColumnMetadata <SecurableResourceType>("Securable_Resource_Type_ID"),
                GetColumnMetadata <Permission>("Permission_ID")
                )
        {
            base.SetValue(0, resourceId);
            base.SetValue(1, resourceType);
            base.SetValue(2, permission);

            ResourceId   = resourceId;
            ResourceType = resourceType;
            Permission   = permission;
        }
 /// <summary>
 /// Initialises a new instance of the <see cref="ResourcePermissionsAttribute"/> class.
 /// </summary>
 /// <param name="resourceType">The type of <see cref="SecurableResource"/> which this parameter refers to the ID of.</param>
 /// <param name="permissionsRequired">The permissions required over the identified <see cref="SecurableResource"/></param>
 public ResourcePermissionsAttribute(SecurableResourceType resourceType, params Permission[] permissionsRequired)
     : base()
 {
     ResourceType        = resourceType;
     PermissionsRequired = permissionsRequired;
 }