Browse Source

Code refactoring and asset protection issue.

pull/613/head
Sebastian 5 years ago
parent
commit
bb0c1cf60e
  1. 2
      backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs
  2. 8
      backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ContributorDto.cs
  3. 21
      backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs
  4. 12
      backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs
  5. 4
      backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs
  6. 2
      backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs
  7. 2
      backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs
  8. 10
      backend/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs
  9. 7
      backend/tools/TestSuite/TestSuite.Shared/Fixtures/AssetFixture.cs

2
backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs

@ -143,7 +143,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
if (app.Image != null)
{
AddGetLink("image", resources.Url<AppsController>(x => nameof(x.GetImage), new { app = app.Name }));
AddGetLink("image", resources.Url<AppsController>(x => nameof(x.GetImage), values));
}
if (isContributor)

8
backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ContributorDto.cs

@ -68,12 +68,16 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
if (resources.CanAssignContributor)
{
AddPostLink("update", resources.Url<AppContributorsController>(x => nameof(x.PostContributor), new { app }));
var values = new { app };
AddPostLink("update", resources.Url<AppContributorsController>(x => nameof(x.PostContributor), values));
}
if (resources.CanRevokeContributor)
{
AddDeleteLink("delete", resources.Url<AppContributorsController>(x => nameof(x.DeleteContributor), new { app, id = ContributorId }));
var values = new { app, id = ContributorId };
AddDeleteLink("delete", resources.Url<AppContributorsController>(x => nameof(x.DeleteContributor), values));
}
}

21
backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs

@ -80,12 +80,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
asset = await assetRepository.FindAssetBySlugAsync(AppId, idOrSlug);
}
if (asset != null && queries.Version > EtagVersion.Any && asset.Version != queries.Version)
{
asset = await assetLoader.GetAsync(App.Id, asset.Id, queries.Version);
}
return DeliverAsset(asset, queries);
return await DeliverAssetAsync(asset, queries);
}
/// <summary>
@ -108,10 +103,10 @@ namespace Squidex.Areas.Api.Controllers.Assets
{
var asset = await assetRepository.FindAssetAsync(id);
return DeliverAsset(asset, queries);
return await DeliverAssetAsync(asset, queries);
}
private IActionResult DeliverAsset(IAssetEntity? asset, AssetContentQueryDto queries)
private async Task<IActionResult> DeliverAssetAsync(IAssetEntity? asset, AssetContentQueryDto queries)
{
queries ??= new AssetContentQueryDto();
@ -127,6 +122,16 @@ namespace Squidex.Areas.Api.Controllers.Assets
return StatusCode(403);
}
if (asset != null && queries.Version > EtagVersion.Any && asset.Version != queries.Version)
{
asset = await assetLoader.GetAsync(App.Id, asset.Id, queries.Version);
}
if (asset == null)
{
return NotFound();
}
var resizeOptions = queries.ToResizeOptions(asset);
FileCallback callback;

12
backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs

@ -203,13 +203,19 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models
if (!string.IsNullOrWhiteSpace(response.Slug))
{
response.AddGetLink("content", resources.Url<AssetContentController>(x => nameof(x.GetAssetContentBySlug), new { app, idOrSlug = response.Id, more = response.Slug }));
var idValues = new { app, idOrSlug = response.Id, more = response.Slug };
response.AddGetLink("content/slug", resources.Url<AssetContentController>(x => nameof(x.GetAssetContentBySlug), new { app, idOrSlug = response.Slug }));
response.AddGetLink("content", resources.Url<AssetContentController>(x => nameof(x.GetAssetContentBySlug), idValues));
var slugValues = new { app, idOrSlug = response.Slug };
response.AddGetLink("content/slug", resources.Url<AssetContentController>(x => nameof(x.GetAssetContentBySlug), slugValues));
}
else
{
response.AddGetLink("content", resources.Url<AssetContentController>(x => nameof(x.GetAssetContentBySlug), new { app, idOrSlug = response.Id }));
var idValues = new { app, idOrSlug = response.Id };
response.AddGetLink("content", resources.Url<AssetContentController>(x => nameof(x.GetAssetContentBySlug), idValues));
}
return response;

4
backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs

@ -70,7 +70,9 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models
{
AddPostLink("create", resources.Url<ContentsController>(x => nameof(x.PostContent), values));
AddPostLink("create/publish", resources.Url<ContentsController>(x => nameof(x.PostContent), values) + "?publish=true");
var publishValues = new { values.app, values.name, publish = true };
AddPostLink("create/publish", resources.Url<ContentsController>(x => nameof(x.PostContent), publishValues));
}
}
}

2
backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs

@ -137,7 +137,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
if (canRun && ruleRunnerService.CanRunFromSnapshots(rule))
{
var snaphshotValues = new { app = resources.App, id = Id, fromSnapshots = true };
var snaphshotValues = new { values.app, values.id, fromSnapshots = true };
AddPutLink("run/snapshots", resources.Url<RulesController>(x => nameof(x.PutRuleRun), snaphshotValues));
}

2
backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldDto.cs

@ -132,7 +132,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
if (Properties is ArrayFieldPropertiesDto)
{
var parentValues = new { app = resources.App, name = schema, parentId = FieldId };
var parentValues = new { values.app, values.name, parentId = FieldId };
AddPostLink("fields/add", resources.Url<SchemaFieldsController>(x => nameof(x.PostNestedField), parentValues));

10
backend/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs

@ -178,6 +178,16 @@ namespace TestSuite.ApiTests
// Should return 403 when not authenticated.
Assert.Contains("403", ex.Message);
}
// STEP 6: Download asset without key and version.
using (var stream = new FileStream("Assets/logo-squared.png", FileMode.Open))
{
var ex = await Assert.ThrowsAsync<HttpRequestException>(() => _.DownloadAsync(asset_1, 0));
// Should return 403 when not authenticated.
Assert.Contains("403", ex.Message);
}
}
[Fact]

7
backend/tools/TestSuite/TestSuite.Shared/Fixtures/AssetFixture.cs

@ -17,7 +17,7 @@ namespace TestSuite.Fixtures
{
public IAssetsClient Assets => Squidex.Assets;
public async Task<MemoryStream> DownloadAsync(AssetDto asset)
public async Task<MemoryStream> DownloadAsync(AssetDto asset, int? version = null)
{
var temp = new MemoryStream();
@ -25,6 +25,11 @@ namespace TestSuite.Fixtures
{
var url = $"{ServerUrl}{asset._links["content"].Href}";
if (version > 0)
{
url += $"?version={version}";
}
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();

Loading…
Cancel
Save