mirror of
https://github.com/Radarr/Radarr.git
synced 2024-10-05 15:47:20 +02:00
New: Don't return API Keys and Passwords via the API
(cherry picked from commit 570be882154e73f8ad1de5b16b957bcb964697fd)
This commit is contained in:
parent
180dafe696
commit
508a15e09a
@ -66,8 +66,7 @@ private static IAutoTaggingSpecification MapSpecification(AutoTaggingSpecificati
|
||||
// Finding the exact current specification isn't possible given the dynamic nature of them and the possibility that multiple
|
||||
// of the same type exist within the same format. Passing in null is safe as long as there never exists a specification that
|
||||
// relies on additional privacy.
|
||||
// TODO: Check ReadFromSchema for third argument
|
||||
var spec = (IAutoTaggingSpecification)SchemaBuilder.ReadFromSchema(resource.Fields, type);
|
||||
var spec = (IAutoTaggingSpecification)SchemaBuilder.ReadFromSchema(resource.Fields, type, null);
|
||||
spec.Name = resource.Name;
|
||||
spec.Negate = resource.Negate;
|
||||
return spec;
|
||||
|
@ -65,7 +65,10 @@ private static ICustomFormatSpecification MapSpecification(CustomFormatSpecifica
|
||||
|
||||
var type = matchingSpec.GetType();
|
||||
|
||||
var spec = (ICustomFormatSpecification)SchemaBuilder.ReadFromSchema(resource.Fields, type);
|
||||
// Finding the exact current specification isn't possible given the dynamic nature of them and the possibility that multiple
|
||||
// of the same type exist within the same format. Passing in null is safe as long as there never exists a specification that
|
||||
// relies on additional privacy.
|
||||
var spec = (ICustomFormatSpecification)SchemaBuilder.ReadFromSchema(resource.Fields, type, null);
|
||||
spec.Name = resource.Name;
|
||||
spec.Negate = resource.Negate;
|
||||
spec.Required = resource.Required;
|
||||
|
@ -32,14 +32,14 @@ public override DownloadClientResource ToResource(DownloadClientDefinition defin
|
||||
return resource;
|
||||
}
|
||||
|
||||
public override DownloadClientDefinition ToModel(DownloadClientResource resource)
|
||||
public override DownloadClientDefinition ToModel(DownloadClientResource resource, DownloadClientDefinition existingDefinition)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var definition = base.ToModel(resource);
|
||||
var definition = base.ToModel(resource, existingDefinition);
|
||||
|
||||
definition.Enable = resource.Enable;
|
||||
definition.Protocol = resource.Protocol;
|
||||
|
@ -43,14 +43,14 @@ public override ImportListResource ToResource(ImportListDefinition definition)
|
||||
return resource;
|
||||
}
|
||||
|
||||
public override ImportListDefinition ToModel(ImportListResource resource)
|
||||
public override ImportListDefinition ToModel(ImportListResource resource, ImportListDefinition existingDefinition)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var definition = base.ToModel(resource);
|
||||
var definition = base.ToModel(resource, existingDefinition);
|
||||
|
||||
definition.Enabled = resource.Enabled;
|
||||
definition.EnableAuto = resource.EnableAuto;
|
||||
|
@ -37,14 +37,14 @@ public override IndexerResource ToResource(IndexerDefinition definition)
|
||||
return resource;
|
||||
}
|
||||
|
||||
public override IndexerDefinition ToModel(IndexerResource resource)
|
||||
public override IndexerDefinition ToModel(IndexerResource resource, IndexerDefinition existingDefinition)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var definition = base.ToModel(resource);
|
||||
var definition = base.ToModel(resource, existingDefinition);
|
||||
|
||||
definition.EnableRss = resource.EnableRss;
|
||||
definition.EnableAutomaticSearch = resource.EnableAutomaticSearch;
|
||||
|
@ -23,14 +23,14 @@ public override MetadataResource ToResource(MetadataDefinition definition)
|
||||
return resource;
|
||||
}
|
||||
|
||||
public override MetadataDefinition ToModel(MetadataResource resource)
|
||||
public override MetadataDefinition ToModel(MetadataResource resource, MetadataDefinition existingDefinition)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var definition = base.ToModel(resource);
|
||||
var definition = base.ToModel(resource, existingDefinition);
|
||||
|
||||
definition.Enable = resource.Enable;
|
||||
|
||||
|
@ -73,14 +73,14 @@ public override NotificationResource ToResource(NotificationDefinition definitio
|
||||
return resource;
|
||||
}
|
||||
|
||||
public override NotificationDefinition ToModel(NotificationResource resource)
|
||||
public override NotificationDefinition ToModel(NotificationResource resource, NotificationDefinition existingDefinition)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
return default(NotificationDefinition);
|
||||
}
|
||||
|
||||
var definition = base.ToModel(resource);
|
||||
var definition = base.ToModel(resource, existingDefinition);
|
||||
|
||||
definition.OnGrab = resource.OnGrab;
|
||||
definition.OnDownload = resource.OnDownload;
|
||||
|
@ -142,7 +142,8 @@ public virtual ActionResult<TProviderResource> UpdateProvider([FromBody] TBulkPr
|
||||
|
||||
private TProviderDefinition GetDefinition(TProviderResource providerResource, bool validate, bool includeWarnings, bool forceValidate)
|
||||
{
|
||||
var definition = _resourceMapper.ToModel(providerResource);
|
||||
var existingDefinition = providerResource.Id > 0 ? _providerFactory.Find(providerResource.Id) : null;
|
||||
var definition = _resourceMapper.ToModel(providerResource, existingDefinition);
|
||||
|
||||
if (validate && (definition.Enable || forceValidate))
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ public virtual TProviderResource ToResource(TProviderDefinition definition)
|
||||
};
|
||||
}
|
||||
|
||||
public virtual TProviderDefinition ToModel(TProviderResource resource)
|
||||
public virtual TProviderDefinition ToModel(TProviderResource resource, TProviderDefinition existingDefinition)
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
@ -64,7 +64,7 @@ public virtual TProviderDefinition ToModel(TProviderResource resource)
|
||||
};
|
||||
|
||||
var configContract = ReflectionExtensions.CoreAssembly.FindTypeByName(definition.ConfigContract);
|
||||
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFromSchema(resource.Fields, configContract);
|
||||
definition.Settings = (IProviderConfig)SchemaBuilder.ReadFromSchema(resource.Fields, configContract, existingDefinition?.Settings);
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ public class Field
|
||||
public string SelectOptionsProviderAction { get; set; }
|
||||
public string Section { get; set; }
|
||||
public string Hidden { get; set; }
|
||||
public PrivacyLevel Privacy { get; set; }
|
||||
public string Placeholder { get; set; }
|
||||
|
||||
public Field Clone()
|
||||
|
@ -13,6 +13,7 @@ namespace Radarr.Http.ClientSchema
|
||||
{
|
||||
public static class SchemaBuilder
|
||||
{
|
||||
private const string PRIVATE_VALUE = "********";
|
||||
private static Dictionary<Type, FieldMapping[]> _mappings = new Dictionary<Type, FieldMapping[]>();
|
||||
|
||||
public static List<Field> ToSchema(object model)
|
||||
@ -26,7 +27,15 @@ public static List<Field> ToSchema(object model)
|
||||
foreach (var mapping in mappings)
|
||||
{
|
||||
var field = mapping.Field.Clone();
|
||||
field.Value = mapping.GetterFunc(model);
|
||||
|
||||
if (field.Privacy == PrivacyLevel.ApiKey || field.Privacy == PrivacyLevel.Password)
|
||||
{
|
||||
field.Value = PRIVATE_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
field.Value = mapping.GetterFunc(model);
|
||||
}
|
||||
|
||||
result.Add(field);
|
||||
}
|
||||
@ -34,7 +43,7 @@ public static List<Field> ToSchema(object model)
|
||||
return result.OrderBy(r => r.Order).ToList();
|
||||
}
|
||||
|
||||
public static object ReadFromSchema(List<Field> fields, Type targetType)
|
||||
public static object ReadFromSchema(List<Field> fields, Type targetType, object model)
|
||||
{
|
||||
Ensure.That(targetType, () => targetType).IsNotNull();
|
||||
|
||||
@ -49,18 +58,25 @@ public static object ReadFromSchema(List<Field> fields, Type targetType)
|
||||
|
||||
if (field != null)
|
||||
{
|
||||
mapping.SetterFunc(target, field.Value);
|
||||
// Use the Privacy property from the mapping's field as Privacy may not be set in the API request (nor is it required)
|
||||
if ((mapping.Field.Privacy == PrivacyLevel.ApiKey || mapping.Field.Privacy == PrivacyLevel.Password) &&
|
||||
(field.Value?.ToString()?.Equals(PRIVATE_VALUE) ?? false) &&
|
||||
model != null)
|
||||
{
|
||||
var existingValue = mapping.GetterFunc(model);
|
||||
|
||||
mapping.SetterFunc(target, existingValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapping.SetterFunc(target, field.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
public static T ReadFromSchema<T>(List<Field> fields)
|
||||
{
|
||||
return (T)ReadFromSchema(fields, typeof(T));
|
||||
}
|
||||
|
||||
// Ideally this function should begin a System.Linq.Expression expression tree since it's faster.
|
||||
// But it's probably not needed till performance issues pop up.
|
||||
public static FieldMapping[] GetFieldMappings(Type type)
|
||||
@ -105,6 +121,7 @@ private static FieldMapping[] GetFieldMapping(Type type, string prefix, Func<obj
|
||||
Advanced = fieldAttribute.Advanced,
|
||||
Type = fieldAttribute.Type.ToString().FirstCharToLower(),
|
||||
Section = fieldAttribute.Section,
|
||||
Privacy = fieldAttribute.Privacy,
|
||||
Placeholder = fieldAttribute.Placeholder
|
||||
};
|
||||
|
||||
@ -132,7 +149,7 @@ private static FieldMapping[] GetFieldMapping(Type type, string prefix, Func<obj
|
||||
Field = field,
|
||||
PropertyType = propertyInfo.PropertyType,
|
||||
GetterFunc = t => propertyInfo.GetValue(targetSelector(t), null),
|
||||
SetterFunc = (t, v) => propertyInfo.SetValue(targetSelector(t), valueConverter(v), null)
|
||||
SetterFunc = (t, v) => propertyInfo.SetValue(targetSelector(t), v?.GetType() == propertyInfo.PropertyType ? v : valueConverter(v), null)
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -255,7 +272,7 @@ private static Func<object, object> GetValueConverter(Type propertyType)
|
||||
}
|
||||
else
|
||||
{
|
||||
return fieldValue.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim());
|
||||
return fieldValue.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user