refactor user details plugin interface
This commit is contained in:
@@ -61,7 +61,7 @@ namespace Disco.Services.Devices.Exporting
|
||||
if (Options.AssignedUserDetailCustom && r.AssignedUser != null)
|
||||
{
|
||||
var detailsService = new DetailsProviderService(Database);
|
||||
r.AssignedUserCustomDetails = detailsService.GetDetails(r.AssignedUser).Details;
|
||||
r.AssignedUserCustomDetails = detailsService.GetDetails(r.AssignedUser);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -208,15 +208,15 @@ namespace Disco.Services.Expressions
|
||||
{
|
||||
if (target is User targetUser)
|
||||
{
|
||||
detailsVariables.Add("UserDetails", new LazyDictionary(() => detailsService.GetDetails(targetUser).Details));
|
||||
detailsVariables.Add("UserDetails", new LazyDictionary(() => detailsService.GetDetails(targetUser)));
|
||||
}
|
||||
else if (target is Job targetJob)
|
||||
{
|
||||
detailsVariables.Add("UserDetails", targetJob.User == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetJob.User).Details));
|
||||
detailsVariables.Add("UserDetails", targetJob.User == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetJob.User)));
|
||||
}
|
||||
else if (target is Device targetDevice)
|
||||
{
|
||||
detailsVariables.Add("UserDetails", targetDevice.AssignedUser == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetDevice.AssignedUser).Details));
|
||||
detailsVariables.Add("UserDetails", targetDevice.AssignedUser == null ? (IDictionary<string, string>)new Dictionary<string, string>() : new LazyDictionary(() => detailsService.GetDetails(targetDevice.AssignedUser)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Disco.Data.Repository;
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Models.Services.Plugins.Details;
|
||||
using System;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.DetailsProvider
|
||||
@@ -8,9 +7,8 @@ namespace Disco.Services.Plugins.Features.DetailsProvider
|
||||
[PluginFeatureCategory(DisplayName = "Detail Providers")]
|
||||
public abstract class DetailsProviderFeature : PluginFeature
|
||||
{
|
||||
public abstract DetailsResult GetDetails(DiscoDataContext database, User user, DateTime? cacheTimestamp);
|
||||
[Obsolete("Never used")]
|
||||
public abstract DetailsResult GetDetails(DiscoDataContext database, Device device, DateTime? cacheTimestamp);
|
||||
public abstract void UpdateAllDetails(DiscoDataContext database);
|
||||
|
||||
public abstract byte[] GetUserPhoto(DiscoDataContext database, User user, DateTime? cacheTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using Disco.Data.Repository;
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Models.Services.Plugins.Details;
|
||||
using Disco.Services.Authorization;
|
||||
using Disco.Services.Users;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -86,77 +85,23 @@ namespace Disco.Services.Plugins.Features.DetailsProvider
|
||||
return Path.Combine(database.DiscoConfiguration.PluginUserPhotosLocation, userHash.Substring(0, 2), $"{userHash}.jpg");
|
||||
}
|
||||
|
||||
public DetailsResult GetDetails(User user)
|
||||
public Dictionary<string, string> GetDetails(User user)
|
||||
{
|
||||
var result = new DetailsResult();
|
||||
var saveChangesRequired = false;
|
||||
|
||||
if (!UserService.CurrentAuthorization.HasAll(Claims.User.Show, Claims.User.ShowDetails))
|
||||
return result;
|
||||
return new Dictionary<string, string>();
|
||||
|
||||
var features = Plugins.GetPluginFeatures(typeof(DetailsProviderFeature));
|
||||
|
||||
if (features.Count == 0)
|
||||
return result;
|
||||
|
||||
var cache = user.UserDetails?.Where(d => d.Scope == DetailsScope).ToDictionary(d => d.Key, d => new { DbDetails = d, Details = JsonConvert.DeserializeObject<DetailsResult>(d.Value) }, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var feature in features)
|
||||
if (user.UserDetails != null)
|
||||
{
|
||||
var featureResult = default(DetailsResult);
|
||||
if (!cache.TryGetValue(feature.Id, out var cacheResult) || cacheResult.Details.ExpiresOn < DateTime.Now || cacheResult.Details.GatheredOn < database.DiscoConfiguration.PluginDetailsCacheExpiration)
|
||||
{
|
||||
var timestamp = cacheResult?.Details.GatheredOn;
|
||||
if (timestamp.HasValue && timestamp.Value < database.DiscoConfiguration.PluginDetailsCacheExpiration)
|
||||
timestamp = null;
|
||||
|
||||
try
|
||||
{
|
||||
var featureInstance = feature.CreateInstance<DetailsProviderFeature>();
|
||||
featureResult = featureInstance.GetDetails(database, user, timestamp);
|
||||
|
||||
if (featureResult != null)
|
||||
{
|
||||
if (featureResult.ExpiresOn > DateTime.Now)
|
||||
{
|
||||
if (cacheResult == null)
|
||||
database.UserDetails.Add(new UserDetail() { UserId = user.UserId, Scope = DetailsScope, Key = feature.Id, Value = JsonConvert.SerializeObject(featureResult) });
|
||||
else
|
||||
cacheResult.DbDetails.Value = JsonConvert.SerializeObject(featureResult);
|
||||
saveChangesRequired = true;
|
||||
}
|
||||
else if (cacheResult != null)
|
||||
{
|
||||
database.UserDetails.Remove(cacheResult.DbDetails);
|
||||
saveChangesRequired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore exceptions when plugins behave badly
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
featureResult = cacheResult.Details;
|
||||
}
|
||||
|
||||
// apply feature results
|
||||
if (featureResult != null)
|
||||
{
|
||||
result.SetExpiration(featureResult.ExpiresOn);
|
||||
foreach (var value in featureResult.Details)
|
||||
{
|
||||
result.Details[value.Key] = value.Value;
|
||||
}
|
||||
}
|
||||
return user.UserDetails
|
||||
.Where(d => string.Equals(d.Scope, DetailsScope, StringComparison.Ordinal))
|
||||
.ToDictionary(d => d.Key, d => d.Value, StringComparer.OrdinalIgnoreCase);
|
||||
} else
|
||||
{
|
||||
return database.UserDetails
|
||||
.Where(d => d.UserId == user.UserId &&
|
||||
d.Scope == DetailsScope)
|
||||
.ToDictionary(d => d.Key, d => d.Value, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (saveChangesRequired)
|
||||
database.SaveChanges();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,10 +67,10 @@ namespace Disco.Services.Users.Contact
|
||||
user = database.Users.First(u => u.UserId == user.UserId);
|
||||
var details = service.GetDetails(user);
|
||||
|
||||
if ((details?.Details?.Count ?? 0) == 0)
|
||||
if ((details?.Count ?? 0) == 0)
|
||||
yield break;
|
||||
|
||||
foreach (var item in details.Details)
|
||||
foreach (var item in details)
|
||||
{
|
||||
if (!contactType.HasValue || contactType.Value.HasFlag(UserContactType.Email))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user