diff options
| author | crobibero <cody@robibe.ro> | 2020-07-20 14:28:33 -0600 |
|---|---|---|
| committer | crobibero <cody@robibe.ro> | 2020-07-20 14:28:33 -0600 |
| commit | 13850644973b1223bbeb2271e42ad252d43a10bf (patch) | |
| tree | 5373b3953dabd692ae937483078569cb0525772e /MediaBrowser.Api/PluginService.cs | |
| parent | 352dab701866b37d0dd5dcaa6343ccc256d7e837 (diff) | |
| parent | 0750357916b600a4b4c27bc4babd2adcc6390473 (diff) | |
Merge remote-tracking branch 'upstream/master' into api-migration-merge
Diffstat (limited to 'MediaBrowser.Api/PluginService.cs')
| -rw-r--r-- | MediaBrowser.Api/PluginService.cs | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs new file mode 100644 index 000000000..7d976ceaa --- /dev/null +++ b/MediaBrowser.Api/PluginService.cs @@ -0,0 +1,277 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using MediaBrowser.Common; +using MediaBrowser.Common.Plugins; +using MediaBrowser.Common.Updates; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Net; +using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Services; +using Microsoft.Extensions.Logging; + +namespace MediaBrowser.Api +{ + /// <summary> + /// Class Plugins. + /// </summary> + [Route("/Plugins", "GET", Summary = "Gets a list of currently installed plugins")] + [Authenticated] + public class GetPlugins : IReturn<PluginInfo[]> + { + public bool? IsAppStoreEnabled { get; set; } + } + + /// <summary> + /// Class UninstallPlugin. + /// </summary> + [Route("/Plugins/{Id}", "DELETE", Summary = "Uninstalls a plugin")] + [Authenticated(Roles = "Admin")] + public class UninstallPlugin : IReturnVoid + { + /// <summary> + /// Gets or sets the id. + /// </summary> + /// <value>The id.</value> + [ApiMember(Name = "Id", Description = "Plugin Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] + public string Id { get; set; } + } + + /// <summary> + /// Class GetPluginConfiguration. + /// </summary> + [Route("/Plugins/{Id}/Configuration", "GET", Summary = "Gets a plugin's configuration")] + [Authenticated] + public class GetPluginConfiguration + { + /// <summary> + /// Gets or sets the id. + /// </summary> + /// <value>The id.</value> + [ApiMember(Name = "Id", Description = "Plugin Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + + /// <summary> + /// Class UpdatePluginConfiguration. + /// </summary> + [Route("/Plugins/{Id}/Configuration", "POST", Summary = "Updates a plugin's configuration")] + [Authenticated] + public class UpdatePluginConfiguration : IRequiresRequestStream, IReturnVoid + { + /// <summary> + /// Gets or sets the id. + /// </summary> + /// <value>The id.</value> + [ApiMember(Name = "Id", Description = "Plugin Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string Id { get; set; } + + /// <summary> + /// The raw Http Request Input Stream. + /// </summary> + /// <value>The request stream.</value> + public Stream RequestStream { get; set; } + } + + // TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins, + // delete all these registration endpoints. They are only kept for compatibility. + [Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] + [Authenticated] + public class GetRegistration : IReturn<RegistrationInfo> + { + [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Name { get; set; } + } + + /// <summary> + /// Class GetPluginSecurityInfo. + /// </summary> + [Route("/Plugins/SecurityInfo", "GET", Summary = "Gets plugin registration information", IsHidden = true)] + [Authenticated] + public class GetPluginSecurityInfo : IReturn<PluginSecurityInfo> + { + } + + /// <summary> + /// Class UpdatePluginSecurityInfo. + /// </summary> + [Route("/Plugins/SecurityInfo", "POST", Summary = "Updates plugin registration information", IsHidden = true)] + [Authenticated(Roles = "Admin")] + public class UpdatePluginSecurityInfo : PluginSecurityInfo, IReturnVoid + { + } + + [Route("/Plugins/RegistrationRecords/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)] + [Authenticated] + public class GetRegistrationStatus + { + [ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Name { get; set; } + } + + // TODO these two classes are only kept for compability with paid plugins and should be removed + public class RegistrationInfo + { + public string Name { get; set; } + + public DateTime ExpirationDate { get; set; } + + public bool IsTrial { get; set; } + + public bool IsRegistered { get; set; } + } + + public class MBRegistrationRecord + { + public DateTime ExpirationDate { get; set; } + + public bool IsRegistered { get; set; } + + public bool RegChecked { get; set; } + + public bool RegError { get; set; } + + public bool TrialVersion { get; set; } + + public bool IsValid { get; set; } + } + + public class PluginSecurityInfo + { + public string SupporterKey { get; set; } + + public bool IsMBSupporter { get; set; } + } + /// <summary> + /// Class PluginsService. + /// </summary> + public class PluginService : BaseApiService + { + /// <summary> + /// The _json serializer. + /// </summary> + private readonly IJsonSerializer _jsonSerializer; + + /// <summary> + /// The _app host. + /// </summary> + private readonly IApplicationHost _appHost; + private readonly IInstallationManager _installationManager; + + public PluginService( + ILogger<PluginService> logger, + IServerConfigurationManager serverConfigurationManager, + IHttpResultFactory httpResultFactory, + IJsonSerializer jsonSerializer, + IApplicationHost appHost, + IInstallationManager installationManager) + : base(logger, serverConfigurationManager, httpResultFactory) + { + _appHost = appHost; + _installationManager = installationManager; + _jsonSerializer = jsonSerializer; + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetRegistrationStatus request) + { + var record = new MBRegistrationRecord + { + IsRegistered = true, + RegChecked = true, + TrialVersion = false, + IsValid = true, + RegError = false + }; + + return ToOptimizedResult(record); + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetPlugins request) + { + var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToArray(); + return ToOptimizedResult(result); + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetPluginConfiguration request) + { + var guid = new Guid(request.Id); + var plugin = _appHost.Plugins.First(p => p.Id == guid) as IHasPluginConfiguration; + + return ToOptimizedResult(plugin.Configuration); + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetPluginSecurityInfo request) + { + var result = new PluginSecurityInfo + { + IsMBSupporter = true, + SupporterKey = "IAmTotallyLegit" + }; + + return ToOptimizedResult(result); + } + + /// <summary> + /// Posts the specified request. + /// </summary> + /// <param name="request">The request.</param> + public Task Post(UpdatePluginSecurityInfo request) + { + return Task.CompletedTask; + } + + /// <summary> + /// Posts the specified request. + /// </summary> + /// <param name="request">The request.</param> + public async Task Post(UpdatePluginConfiguration request) + { + // We need to parse this manually because we told service stack not to with IRequiresRequestStream + // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs + var id = Guid.Parse(GetPathValue(1)); + + if (!(_appHost.Plugins.First(p => p.Id == id) is IHasPluginConfiguration plugin)) + { + throw new FileNotFoundException(); + } + + var configuration = (await _jsonSerializer.DeserializeFromStreamAsync(request.RequestStream, plugin.ConfigurationType).ConfigureAwait(false)) as BasePluginConfiguration; + + plugin.UpdateConfiguration(configuration); + } + + /// <summary> + /// Deletes the specified request. + /// </summary> + /// <param name="request">The request.</param> + public void Delete(UninstallPlugin request) + { + var guid = new Guid(request.Id); + var plugin = _appHost.Plugins.First(p => p.Id == guid); + + _installationManager.UninstallPlugin(plugin); + } + } +} |
