diff --git a/Oqtane.Client/Modules/Admin/Languages/Index.razor b/Oqtane.Client/Modules/Admin/Languages/Index.razor index 72892e51..19b3be19 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Index.razor @@ -146,7 +146,7 @@ else { try { - _package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, version); + _package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, version, false); if (_package != null) { StateHasChanged(); @@ -168,7 +168,7 @@ else { try { - await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder); + await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version); await logger.LogInformation("Language Package {Name} {Version} Downloaded Successfully", _package.PackageId, _package.Version); AddModuleMessage(string.Format(Localizer["Success.Language.Download"], NavigateUrl("admin/system")), MessageType.Success); _package = null; diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor index 059b4a9b..8a4e2850 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor @@ -263,7 +263,7 @@ { try { - var package = await PackageService.GetPackageAsync(packageid, version); + var package = await PackageService.GetPackageAsync(packageid, version, false); if (package != null) { _productname = package.Name; @@ -292,7 +292,7 @@ { try { - await PackageService.DownloadPackageAsync(_packageid, _packageversion, Constants.PackagesFolder); + await PackageService.DownloadPackageAsync(_packageid, _packageversion); await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _packageversion); AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success); _productname = ""; diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor index f7da5778..23ed0ccc 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor @@ -61,7 +61,24 @@
- + @if (!string.IsNullOrEmpty(_packagename)) + { +
+ + @if (string.IsNullOrEmpty(_packageurl)) + { + + } + else + { + @SharedLocalizer["Download"] + } +
+ } + else + { + + }
@@ -191,7 +208,7 @@

@@ -213,6 +230,7 @@ private string _moduledefinitionname = ""; private string _version; private string _packagename = ""; + private string _packageurl = ""; private string _owner = ""; private string _url = ""; private string _contact = ""; @@ -364,7 +382,7 @@ var version = _packages.Where(item => item.PackageId == packagename).FirstOrDefault().Version; try { - _package = await PackageService.GetPackageAsync(packagename, version); + _package = await PackageService.GetPackageAsync(packagename, version, false); if (_package != null) { StateHasChanged(); @@ -382,11 +400,11 @@ } } - private async Task DownloadPackage() + private async Task DownloadTranslation() { try { - await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder); + await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version); await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _package.PackageId, _package.Version); AddModuleMessage(string.Format(Localizer["Success.Translation.Download"], NavigateUrl("admin/system")), MessageType.Success); _package = null; @@ -398,4 +416,28 @@ AddModuleMessage(Localizer["Error.Translation.Download"], MessageType.Error); } } + + private async Task ValidatePackage() + { + try + { + var package = await PackageService.GetPackageAsync(_packagename, _version, true); + if (package == null || string.IsNullOrEmpty(package.PackageUrl)) + { + AddModuleMessage(Localizer["Message.Validate"], MessageType.Warning); + } + else + { + _packageurl = package.PackageUrl; + AddModuleMessage(Localizer["Message.Download"], MessageType.Info); + } + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Downloading Package {PackageId} {Version}", _packagename, _version); + AddModuleMessage(Localizer["Error.Validate"], MessageType.Error); + } + } + } diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index ee962a80..2d3b80a7 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -128,8 +128,7 @@ else private async Task LoadModuleDefinitions() { _moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList(); - var list = _moduleDefinitions.Where(item => !string.IsNullOrEmpty(item.PackageName)).Select(item => item.PackageName).Distinct().ToList(); - _packages = await PackageService.GetPackagesAsync(list); + _packages = await PackageService.GetPackageUpdatesAsync("module"); } private string PurchaseLink(string packagename) @@ -187,7 +186,7 @@ else { try { - await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder); + await PackageService.DownloadPackageAsync(packagename, version); await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version); AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success); } diff --git a/Oqtane.Client/Modules/Admin/Themes/Add.razor b/Oqtane.Client/Modules/Admin/Themes/Add.razor index c7364095..3b22ef3c 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Add.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Add.razor @@ -263,7 +263,7 @@ { try { - var package = await PackageService.GetPackageAsync(packageid, version); + var package = await PackageService.GetPackageAsync(packageid, version, false); if (package != null) { _productname = package.Name; @@ -292,7 +292,7 @@ { try { - await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder); + await PackageService.DownloadPackageAsync(_packageid, _version); await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version); AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success); _productname = ""; diff --git a/Oqtane.Client/Modules/Admin/Themes/Edit.razor b/Oqtane.Client/Modules/Admin/Themes/Edit.razor index 53cbae7e..92dcf3a8 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Edit.razor @@ -2,6 +2,7 @@ @using System.Net @inherits ModuleBase @inject IThemeService ThemeService +@inject IPackageService PackageService @inject NavigationManager NavigationManager @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer @@ -44,8 +45,25 @@
- -
+ @if (!string.IsNullOrEmpty(_packagename)) + { +
+ + @if (string.IsNullOrEmpty(_packageurl)) + { + + } + else + { + @SharedLocalizer["Download"] + } +
+ } + else + { + + } +
@@ -97,7 +115,8 @@ private string _isenabled; private string _name; private string _version; - private string _packagename; + private string _packagename = ""; + private string _packageurl = ""; private string _owner = ""; private string _url = ""; private string _contact = ""; @@ -166,4 +185,27 @@ AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning); } } + + private async Task ValidatePackage() + { + try + { + var package = await PackageService.GetPackageAsync(_packagename, _version, true); + if (package == null || string.IsNullOrEmpty(package.PackageUrl)) + { + AddModuleMessage(Localizer["Message.Validate"], MessageType.Warning); + } + else + { + _packageurl = package.PackageUrl; + AddModuleMessage(Localizer["Message.Download"], MessageType.Info); + } + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Downloading Package {PackageId} {Version}", _packagename, _version); + AddModuleMessage(Localizer["Error.Validate"], MessageType.Error); + } + } } diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 753451cc..3a7d64ae 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -79,8 +79,7 @@ else try { _themes = await ThemeService.GetThemesAsync(); - var list = _themes.Where(item => !string.IsNullOrEmpty(item.PackageName)).Select(item => item.PackageName).Distinct().ToList(); - _packages = await PackageService.GetPackagesAsync(list); + _packages = await PackageService.GetPackageUpdatesAsync("theme"); } catch (Exception ex) { @@ -147,7 +146,7 @@ else { try { - await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder); + await PackageService.DownloadPackageAsync(packagename, version); await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version); AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success); } diff --git a/Oqtane.Client/Modules/Admin/Upgrade/Index.razor b/Oqtane.Client/Modules/Admin/Upgrade/Index.razor index 5bf8d48e..2ea14802 100644 --- a/Oqtane.Client/Modules/Admin/Upgrade/Index.razor +++ b/Oqtane.Client/Modules/Admin/Upgrade/Index.razor @@ -85,8 +85,8 @@ { try { - await PackageService.DownloadPackageAsync(packageid, version, Constants.PackagesFolder); - await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, version, Constants.PackagesFolder); + await PackageService.DownloadPackageAsync(packageid, version); + await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, version); AddModuleMessage(Localizer["Success.Framework.Download"], MessageType.Success); } catch (Exception ex) diff --git a/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx index 5cd18d11..87cc9a12 100644 --- a/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx @@ -228,4 +228,16 @@ View License + + Error Validating Package + + + Package Version Has Been Verified. Please Select The Download Button To Obtain The Package. + + + This Package Version Has Not Been Registered In The Oqtane Marketplace Or You Do Not Have The Right To Use It From This Installation + + + Validate + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Themes/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/Themes/Edit.resx index c18f9761..58a04abe 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Themes/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Themes/Edit.resx @@ -180,4 +180,16 @@ View License + + Error Validating Package + + + Package Version Has Been Verified. Please Select The Download Button To Obtain The Package. + + + This Package Version Has Not Been Registered In The Oqtane Marketplace Or You Do Not Have The Right To Use It From This Installation + + + Validate + \ No newline at end of file diff --git a/Oqtane.Client/Services/Interfaces/IPackageService.cs b/Oqtane.Client/Services/Interfaces/IPackageService.cs index 9887804d..ff930ccc 100644 --- a/Oqtane.Client/Services/Interfaces/IPackageService.cs +++ b/Oqtane.Client/Services/Interfaces/IPackageService.cs @@ -39,11 +39,10 @@ namespace Oqtane.Services Task> GetPackagesAsync(string type, string search, string price, string package, string sort); /// - /// Returns a list of packages matching the list of package names + /// Returns a list of packages based on installationid /// - /// /// - Task> GetPackagesAsync(List packagenames); + Task> GetPackageUpdatesAsync(string type); /// /// Returns a specific package @@ -51,7 +50,7 @@ namespace Oqtane.Services /// /// /// - Task GetPackageAsync(string packageId, string version); + Task GetPackageAsync(string packageId, string version, bool download); /// /// Downloads a specific package as .nupkg file @@ -60,7 +59,7 @@ namespace Oqtane.Services /// /// /// - Task DownloadPackageAsync(string packageId, string version, string folder); + Task DownloadPackageAsync(string packageId, string version); /// /// Installs all packages located in //TODO: 2dm where? diff --git a/Oqtane.Client/Services/PackageService.cs b/Oqtane.Client/Services/PackageService.cs index 7afeebf0..3e2ad61c 100644 --- a/Oqtane.Client/Services/PackageService.cs +++ b/Oqtane.Client/Services/PackageService.cs @@ -31,19 +31,19 @@ namespace Oqtane.Services return await GetJsonAsync>($"{Apiurl}?type={type}&search={WebUtility.UrlEncode(search)}&price={price}&package={package}&sort={sort}"); } - public async Task> GetPackagesAsync(List packagenames) + public async Task> GetPackageUpdatesAsync(string type) { - return await GetJsonAsync>($"{Apiurl}/list/?names={string.Join(",", packagenames)}"); + return await GetJsonAsync>($"{Apiurl}/updates/?type={type}"); } - public async Task GetPackageAsync(string packageId, string version) + public async Task GetPackageAsync(string packageId, string version, bool download) { - return await PostJsonAsync($"{Apiurl}?packageid={packageId}&version={version}", null); + return await PostJsonAsync($"{Apiurl}?packageid={packageId}&version={version}&download={download}&install=false", null); } - public async Task DownloadPackageAsync(string packageId, string version, string folder) + public async Task DownloadPackageAsync(string packageId, string version) { - await PostAsync($"{Apiurl}?packageid={packageId}&version={version}&folder={folder}"); + await PostAsync($"{Apiurl}?packageid={packageId}&version={version}&download=true&install=true"); } public async Task InstallPackagesAsync() diff --git a/Oqtane.Server/Controllers/PackageController.cs b/Oqtane.Server/Controllers/PackageController.cs index 7463bff4..795eb525 100644 --- a/Oqtane.Server/Controllers/PackageController.cs +++ b/Oqtane.Server/Controllers/PackageController.cs @@ -51,20 +51,20 @@ namespace Oqtane.Controllers return packages; } - // GET: api//list/?names=x,y,z - [HttpGet("list")] - public async Task> GetPackages(string names) + // GET: api//updates/?type=x + [HttpGet("updates")] + public async Task> GetPackageUpdates(string type) { // get packages List packages = new List(); var url = _configManager.GetSetting("PackageRegistryUrl", Constants.PackageRegistryUrl); - if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(names)) + if (!string.IsNullOrEmpty(url)) { using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("Referer", HttpContext.Request.Scheme + "://" + HttpContext.Request.Host.Value); client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(Constants.PackageId, Constants.Version)); - packages = await GetJson>(client, url + $"/api/registry/list/?id={_configManager.GetInstallationId()}&version={Constants.Version}&list={names}"); + packages = await GetJson>(client, url + $"/api/registry/updates/?id={_configManager.GetInstallationId()}&version={Constants.Version}&type={type}"); } } return packages; @@ -72,14 +72,13 @@ namespace Oqtane.Controllers [HttpPost] [Authorize(Roles = RoleNames.Host)] - public async Task Post(string packageid, string version, string folder) + public async Task Post(string packageid, string version, string download, string install) { // get package info Package package = null; var url = _configManager.GetSetting("PackageRegistryUrl", Constants.PackageRegistryUrl); if (!string.IsNullOrEmpty(url)) { - var download = (string.IsNullOrEmpty(folder)) ? "false" : "true"; using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("Referer", HttpContext.Request.Scheme + "://" + HttpContext.Request.Host.Value); @@ -89,16 +88,16 @@ namespace Oqtane.Controllers if (package != null) { - if (bool.Parse(download)) + if (bool.Parse(install)) { using (var httpClient = new HttpClient()) { - folder = Path.Combine(_environment.ContentRootPath, folder); + var folder = Path.Combine(_environment.ContentRootPath, Constants.PackagesFolder); var response = await httpClient.GetAsync(package.PackageUrl).ConfigureAwait(false); if (response.IsSuccessStatusCode) { string filename = packageid + "." + version + ".nupkg"; - using (var fileStream = new FileStream(Path.Combine(folder, filename), FileMode.Create, FileAccess.Write, FileShare.None)) + using (var fileStream = new FileStream(Path.Combine(Constants.PackagesFolder, filename), FileMode.Create, FileAccess.Write, FileShare.None)) { await response.Content.CopyToAsync(fileStream).ConfigureAwait(false); } @@ -112,7 +111,7 @@ namespace Oqtane.Controllers } else { - _logger.Log(LogLevel.Error, this, LogFunction.Create, "Package {PackageId}.{Version} Is Not Registered", packageid, version); + _logger.Log(LogLevel.Error, this, LogFunction.Create, "Package {PackageId}.{Version} Is Not Registered In The Marketplace", packageid, version); } } return package; @@ -120,17 +119,31 @@ namespace Oqtane.Controllers private async Task GetJson(HttpClient httpClient, string url) { - Uri uri = new Uri(url); - var response = await httpClient.GetAsync(uri).ConfigureAwait(false); - if (response.IsSuccessStatusCode) + try { - var stream = await response.Content.ReadAsStreamAsync(); - using (var streamReader = new StreamReader(stream)) + Uri uri = new Uri(url); + var response = await httpClient.GetAsync(uri).ConfigureAwait(false); + if (response.IsSuccessStatusCode && ValidateJsonContent(response.Content)) { - return await JsonSerializer.DeserializeAsync(stream, new JsonSerializerOptions(JsonSerializerDefaults.Web)); + var stream = await response.Content.ReadAsStreamAsync(); + using (var streamReader = new StreamReader(stream)) + { + return await JsonSerializer.DeserializeAsync(stream, new JsonSerializerOptions(JsonSerializerDefaults.Web)); + } } + return default(T); } - return default(T); + catch (Exception ex) + { + _logger.Log(LogLevel.Error, this, LogFunction.Read, ex, "Error Accessing Marketplace API {Url}", url); + return default(T); + } + } + + private static bool ValidateJsonContent(HttpContent content) + { + var mediaType = content?.Headers.ContentType?.MediaType; + return mediaType != null && mediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase); } [HttpGet("install")]