Browse Source

Domainid fixes

pull/590/head
Sebastian 5 years ago
parent
commit
4735179b5c
  1. 2
      backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs
  2. 4
      backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs
  3. 2
      backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs
  4. 2
      backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs
  5. 5
      backend/src/Migrations/OldTriggers/ContentChangedTriggerSchema.cs
  6. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs
  7. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs
  8. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventFluidExtensions.cs
  9. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs
  10. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs
  11. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs
  12. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryContent.cs
  13. 7
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventEntity.cs
  14. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs
  15. 4
      backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs
  16. 4
      backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs
  17. 6
      backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs
  18. 4
      backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsLoader.cs
  19. 2
      backend/src/Squidex.Domain.Apps.Entities/Comments/ICommentsLoader.cs
  20. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs
  21. 5
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs
  22. 5
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AssetActions.cs
  23. 22
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentActions.cs
  24. 4
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs
  25. 5
      backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs
  26. 2
      backend/src/Squidex.Domain.Apps.Entities/Q.cs
  27. 2
      backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs
  28. 27
      backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoEntity.cs
  29. 2
      backend/src/Squidex.Infrastructure/Commands/DomainObject.cs
  30. 2
      backend/src/Squidex.Infrastructure/Commands/DomainObjectGrain.cs
  31. 6
      backend/src/Squidex.Infrastructure/Commands/LogSnapshotDomainObject.cs
  32. 10
      backend/src/Squidex.Infrastructure/DomainId.cs
  33. 2
      backend/src/Squidex.Infrastructure/DomainIdTypeConverter.cs
  34. 2
      backend/src/Squidex.Infrastructure/EventSourcing/EnvelopeExtensions.cs
  35. 4
      backend/src/Squidex.Infrastructure/Json/Newtonsoft/NamedDomainIdConverter.cs
  36. 4
      backend/src/Squidex.Web/Pipeline/SchemaResolver.cs
  37. 5
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppPatternsController.cs
  38. 5
      backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs
  39. 3
      backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdatePatternDto.cs
  40. 2
      backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateWorkflowDto.cs
  41. 4
      backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs
  42. 17
      backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs
  43. 19
      backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs
  44. 3
      backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AnnotateAssetDto.cs
  45. 2
      backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetItemDto.cs
  46. 3
      backend/src/Squidex/Areas/Api/Controllers/Assets/Models/RenameAssetFolderDto.cs
  47. 3
      backend/src/Squidex/Areas/Api/Controllers/Backups/BackupContentController.cs
  48. 3
      backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs
  49. 20
      backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs
  50. 5
      backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs
  51. 14
      backend/src/Squidex/Areas/Api/Controllers/Comments/Notifications/UserNotificationsController.cs
  52. 25
      backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs
  53. 3
      backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ChangeStatusDto.cs
  54. 3
      backend/src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs
  55. 20
      backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs
  56. 5
      backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs
  57. 3
      backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs
  58. 4
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs
  59. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentsCommandMiddlewareTests.cs
  60. 4
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentsLoaderTests.cs
  61. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs
  62. 2
      backend/tests/Squidex.Infrastructure.Tests/Commands/CommandContextTests.cs
  63. 3
      backend/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs
  64. 2
      backend/tests/Squidex.Web.Tests/CommandMiddlewares/EnrichWithSchemaIdCommandMiddlewareTests.cs
  65. 24
      backend/tests/Squidex.Web.Tests/Pipeline/CachingFilterTests.cs

2
backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs

@ -48,7 +48,7 @@ namespace Squidex.Extensions.Actions.Comment
ruleJob.Actor = contentEvent.Actor; ruleJob.Actor = contentEvent.Actor;
} }
ruleJob.CommentsId = contentEvent.Id.ToString(); ruleJob.CommentsId = contentEvent.Id;
return (Description, ruleJob); return (Description, ruleJob);
} }

4
backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs

@ -55,7 +55,9 @@ namespace Squidex.Extensions.Actions.Notification
throw new InvalidOperationException($"Cannot find user by '{action.User}'"); throw new InvalidOperationException($"Cannot find user by '{action.User}'");
} }
var ruleJob = new CreateComment { Actor = actor, CommentsId = user.Id, Text = text }; var commentsId = DomainId.Create(user.Id);
var ruleJob = new CreateComment { Actor = actor, CommentsId = commentsId, Text = text };
if (!string.IsNullOrWhiteSpace(action.Url)) if (!string.IsNullOrWhiteSpace(action.Url))
{ {

2
backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs

@ -67,7 +67,7 @@ namespace Migrations.Migrations.MongoDb
var domainType = eventStream.Substring(0, indexOfType); var domainType = eventStream.Substring(0, indexOfType);
var domainId = eventStream.Substring(indexOfId); var domainId = eventStream.Substring(indexOfId);
var newDomainId = DomainId.Combine(appId, domainId).ToString(); var newDomainId = DomainId.Combine(DomainId.Create(appId), DomainId.Create(domainId)).ToString();
var newStreamName = $"{domainType}-{newDomainId}"; var newStreamName = $"{domainType}-{newDomainId}";
document["EventStream"] = newStreamName; document["EventStream"] = newStreamName;

2
backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs

@ -111,7 +111,7 @@ namespace Migrations.Migrations.MongoDb
documentIdOld = documentIdOld.Substring(index + 2); documentIdOld = documentIdOld.Substring(index + 2);
} }
var documentIdNew = DomainId.Combine(appId, documentIdOld).ToString(); var documentIdNew = DomainId.Combine(DomainId.Create(appId), DomainId.Create(documentIdOld)).ToString();
document["id"] = documentIdOld; document["id"] = documentIdOld;
document["_id"] = documentIdNew; document["_id"] = documentIdNew;

5
backend/src/Migrations/OldTriggers/ContentChangedTriggerSchema.cs

@ -10,6 +10,7 @@ using System.Collections.Generic;
using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Rules.Triggers; using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Infrastructure;
namespace Migrations.OldTriggers namespace Migrations.OldTriggers
{ {
@ -71,7 +72,9 @@ namespace Migrations.OldTriggers
condition = string.Join(" || ", conditions); condition = string.Join(" || ", conditions);
} }
return new ContentChangedTriggerSchemaV2 { SchemaId = SchemaId, Condition = condition }; var schemaId = DomainId.Create(SchemaId);
return new ContentChangedTriggerSchemaV2 { SchemaId = schemaId, Condition = condition };
} }
} }
} }

2
backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs

@ -112,7 +112,7 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
private bool IsValidReference(IJsonValue item) private bool IsValidReference(IJsonValue item)
{ {
return item is JsonString s && validIds.Contains(s.Value); return item is JsonString s && validIds.Contains(DomainId.Create(s.Value));
} }
} }
} }

2
backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs

@ -23,7 +23,7 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
if (id is JsonString s) if (id is JsonString s)
{ {
result.Add(s.Value); result.Add(DomainId.Create(s.Value));
added++; added++;

2
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventFluidExtensions.cs

@ -43,7 +43,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Extensions
{ {
if (context.GetValue("event")?.ToObjectValue() is EnrichedContentEvent contentEvent) if (context.GetValue("event")?.ToObjectValue() is EnrichedContentEvent contentEvent)
{ {
var result = urlGenerator.ContentUI(contentEvent.AppId, contentEvent.SchemaId, id.ToString()); var result = urlGenerator.ContentUI(contentEvent.AppId, contentEvent.SchemaId, id);
return new StringValue(result); return new StringValue(result);
} }

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetFolderRepository.cs

@ -71,7 +71,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
{ {
using (Profiler.TraceMethod<MongoAssetFolderRepository>()) using (Profiler.TraceMethod<MongoAssetFolderRepository>())
{ {
var documentId = DomainId.Combine(appId, id).ToString(); var documentId = DomainId.Combine(appId, id);
var assetFolderEntity = var assetFolderEntity =
await Collection.Find(x => x.DocumentId == documentId && !x.IsDeleted) await Collection.Find(x => x.DocumentId == documentId && !x.IsDeleted)

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/MongoAssetRepository.cs

@ -157,7 +157,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Assets
{ {
using (Profiler.TraceMethod<MongoAssetRepository>()) using (Profiler.TraceMethod<MongoAssetRepository>())
{ {
var documentId = DomainId.Combine(appId, id).ToString(); var documentId = DomainId.Combine(appId, id);
var assetEntity = var assetEntity =
await Collection.Find(x => x.DocumentId == documentId && !x.IsDeleted) await Collection.Find(x => x.DocumentId == documentId && !x.IsDeleted)

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs

@ -104,7 +104,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents
private Task DeletePublishedContentAsync(DomainId appId, DomainId id) private Task DeletePublishedContentAsync(DomainId appId, DomainId id)
{ {
var documentId = DomainId.Combine(appId, id).ToString(); var documentId = DomainId.Combine(appId, id);
return collectionPublished.RemoveAsync(documentId); return collectionPublished.RemoveAsync(documentId);
} }

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryContent.cs

@ -26,7 +26,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations
{ {
Guard.NotNull(schema, nameof(schema)); Guard.NotNull(schema, nameof(schema));
var documentId = DomainId.Combine(schema.AppId, id).ToString(); var documentId = DomainId.Combine(schema.AppId, id);
var find = Collection.Find(x => x.DocumentId == documentId); var find = Collection.Find(x => x.DocumentId == documentId);

7
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventEntity.cs

@ -16,8 +16,13 @@ using Squidex.Infrastructure.MongoDb;
namespace Squidex.Domain.Apps.Entities.MongoDb.Rules namespace Squidex.Domain.Apps.Entities.MongoDb.Rules
{ {
public sealed class MongoRuleEventEntity : MongoEntity, IRuleEventEntity [BsonIgnoreExtraElements]
public sealed class MongoRuleEventEntity : IRuleEventEntity
{ {
[BsonId]
[BsonElement]
public DomainId DocumentId { get; set; }
[BsonRequired] [BsonRequired]
[BsonElement] [BsonElement]
public DomainId AppId { get; set; } public DomainId AppId { get; set; }

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Rules/MongoRuleEventRepository.cs

@ -101,7 +101,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Rules
SimpleMapper.Map(job, entity); SimpleMapper.Map(job, entity);
entity.DocumentId = job.Id.ToString(); entity.DocumentId = job.Id;
await Collection.InsertOneIfNotExistsAsync(entity, ct); await Collection.InsertOneIfNotExistsAsync(entity, ct);
} }

4
backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs

@ -207,7 +207,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
{ {
await index.AddAsync(token); await index.AddAsync(token);
await Index(createApp.Actor.Identifier).AddAsync(createApp.AppId.ToString()); await Index(createApp.Actor.Identifier).AddAsync(createApp.AppId);
} }
else else
{ {
@ -253,7 +253,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
if (name.IsSlug()) if (name.IsSlug())
{ {
var token = await index.ReserveAsync(command.AppId.ToString(), name); var token = await index.ReserveAsync(command.AppId, name);
if (token == null) if (token == null)
{ {

4
backend/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs

@ -132,6 +132,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
try try
{ {
var appId = DomainId.Create(Key);
using (var stream = backupArchiveLocation.OpenStream(job.Id)) using (var stream = backupArchiveLocation.OpenStream(job.Id))
{ {
using (var writer = await backupArchiveLocation.OpenWriterAsync(stream)) using (var writer = await backupArchiveLocation.OpenWriterAsync(stream))
@ -140,7 +142,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
var userMapping = new UserMapping(actor); var userMapping = new UserMapping(actor);
var context = new BackupContext(Key, userMapping, writer); var context = new BackupContext(appId, userMapping, writer);
await eventStore.QueryAsync(async storedEvent => await eventStore.QueryAsync(async storedEvent =>
{ {

6
backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs

@ -324,7 +324,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
{ {
if (@event.Payload is AppCreated appCreated) if (@event.Payload is AppCreated appCreated)
{ {
var previousAppId = appCreated.AppId.Id.ToString(); var previousAppId = appCreated.AppId.Id;
if (!string.IsNullOrWhiteSpace(CurrentJob.NewAppName)) if (!string.IsNullOrWhiteSpace(CurrentJob.NewAppName))
{ {
@ -363,7 +363,9 @@ namespace Squidex.Domain.Apps.Entities.Backup
restoreContext.PreviousAppId.ToString(), restoreContext.PreviousAppId.ToString(),
restoreContext.AppId.ToString()); restoreContext.AppId.ToString());
@event.SetAggregateId(id); var domainId = DomainId.Create(id);
@event.SetAggregateId(domainId);
} }
foreach (var handler in handlers) foreach (var handler in handlers)

4
backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsLoader.cs

@ -20,9 +20,9 @@ namespace Squidex.Domain.Apps.Entities.Comments
this.grainFactory = grainFactory; this.grainFactory = grainFactory;
} }
public Task<CommentsResult> GetCommentsAsync(string id, long version = EtagVersion.Any) public Task<CommentsResult> GetCommentsAsync(DomainId id, long version = EtagVersion.Any)
{ {
var grain = grainFactory.GetGrain<ICommentsGrain>(id); var grain = grainFactory.GetGrain<ICommentsGrain>(id.ToString());
return grain.GetCommentsAsync(version); return grain.GetCommentsAsync(version);
} }

2
backend/src/Squidex.Domain.Apps.Entities/Comments/ICommentsLoader.cs

@ -12,6 +12,6 @@ namespace Squidex.Domain.Apps.Entities.Comments
{ {
public interface ICommentsLoader public interface ICommentsLoader
{ {
Task<CommentsResult> GetCommentsAsync(string id, long version = EtagVersion.Any); Task<CommentsResult> GetCommentsAsync(DomainId id, long version = EtagVersion.Any);
} }
} }

2
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs

@ -141,7 +141,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
{ {
foreach (var id in array) foreach (var id in array)
{ {
result.Add(id.ToString()); result.Add(DomainId.Create(id.ToString()));
} }
} }

5
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs

@ -34,6 +34,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
public bool CanGenerateAssetSourceUrl { get; } public bool CanGenerateAssetSourceUrl { get; }
static GraphQLModel()
{
ValueConverter.Register<string, DomainId>(DomainId.Create);
}
public GraphQLModel(IAppEntity app, public GraphQLModel(IAppEntity app,
IEnumerable<ISchemaEntity> schemas, IEnumerable<ISchemaEntity> schemas,
int pageSizeContents, int pageSizeContents,

5
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AssetActions.cs

@ -10,6 +10,7 @@ using GraphQL;
using GraphQL.Resolvers; using GraphQL.Resolvers;
using GraphQL.Types; using GraphQL.Types;
using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
{ {
@ -56,9 +57,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public static readonly IFieldResolver Resolver = new FuncFieldResolver<object?>(c => public static readonly IFieldResolver Resolver = new FuncFieldResolver<object?>(c =>
{ {
var id = c.GetArgument<Guid>("id"); var assetId = c.GetArgument<DomainId>("id");
return ((GraphQLExecutionContext)c.UserContext).FindAssetAsync(id); return ((GraphQLExecutionContext)c.UserContext).FindAssetAsync(assetId);
}); });
} }

22
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentActions.cs

@ -76,9 +76,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public static readonly IFieldResolver Resolver = new FuncFieldResolver<object?>(c => public static readonly IFieldResolver Resolver = new FuncFieldResolver<object?>(c =>
{ {
var id = c.GetArgument<Guid>("id"); var contentId = c.GetArgument<DomainId>("id");
return ((GraphQLExecutionContext)c.UserContext).FindContentAsync(id); return ((GraphQLExecutionContext)c.UserContext).FindContentAsync(contentId);
}); });
} }
@ -183,7 +183,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
if (!string.IsNullOrWhiteSpace(contentId)) if (!string.IsNullOrWhiteSpace(contentId))
{ {
command.ContentId = contentId; var id = DomainId.Create(contentId);
command.ContentId = id;
} }
return command; return command;
@ -236,7 +238,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
var contentData = GetContentData(c); var contentData = GetContentData(c);
var contentId = c.GetArgument<string>("id"); var contentId = c.GetArgument<string>("id");
return new UpsertContent { ContentId = contentId, Data = contentData, Publish = contentPublish }; var id = DomainId.Create(contentId);
return new UpsertContent { ContentId = id, Data = contentData, Publish = contentPublish };
}); });
} }
} }
@ -275,7 +279,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
{ {
return ResolveAsync<IEnrichedContentEntity>(appId, schemaId, c => return ResolveAsync<IEnrichedContentEntity>(appId, schemaId, c =>
{ {
var contentId = c.GetArgument<Guid>("id"); var contentId = c.GetArgument<DomainId>("id");
var contentData = GetContentData(c); var contentData = GetContentData(c);
return new UpdateContent { ContentId = contentId, Data = contentData }; return new UpdateContent { ContentId = contentId, Data = contentData };
@ -317,7 +321,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
{ {
return ResolveAsync<IEnrichedContentEntity>(appId, schemaId, c => return ResolveAsync<IEnrichedContentEntity>(appId, schemaId, c =>
{ {
var contentId = c.GetArgument<Guid>("id"); var contentId = c.GetArgument<DomainId>("id");
var contentData = GetContentData(c); var contentData = GetContentData(c);
return new PatchContent { ContentId = contentId, Data = contentData }; return new PatchContent { ContentId = contentId, Data = contentData };
@ -363,7 +367,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
{ {
return ResolveAsync<IEnrichedContentEntity>(appId, schemaId, c => return ResolveAsync<IEnrichedContentEntity>(appId, schemaId, c =>
{ {
var contentId = c.GetArgument<Guid>("id"); var contentId = c.GetArgument<DomainId>("id");
var contentStatus = new Status(c.GetArgument<string>("status")); var contentStatus = new Status(c.GetArgument<string>("status"));
var contentDueTime = c.GetArgument<Instant?>("dueTime"); var contentDueTime = c.GetArgument<Instant?>("dueTime");
@ -381,7 +385,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
Name = "id", Name = "id",
Description = "The id of the content (usually GUID)", Description = "The id of the content (usually GUID)",
DefaultValue = null, DefaultValue = null,
ResolvedType = AllTypes.NonNullGuid ResolvedType = AllTypes.NonNullString
}, },
new QueryArgument(AllTypes.None) new QueryArgument(AllTypes.None)
{ {
@ -396,7 +400,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
{ {
return ResolveAsync<EntitySavedResult>(appId, schemaId, c => return ResolveAsync<EntitySavedResult>(appId, schemaId, c =>
{ {
var contentId = c.GetArgument<Guid>("id"); var contentId = c.GetArgument<DomainId>("id");
return new DeleteContent { ContentId = contentId }; return new DeleteContent { ContentId = contentId };
}); });

4
backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs

@ -161,7 +161,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
if (Guid.TryParse(schemaIdOrName, out var guid)) if (Guid.TryParse(schemaIdOrName, out var guid))
{ {
schema = await appProvider.GetSchemaAsync(context.App.Id, guid, false, canCache); var schemaId = DomainId.Create(guid);
schema = await appProvider.GetSchemaAsync(context.App.Id, schemaId, false, canCache);
} }
if (schema == null) if (schema == null)

5
backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs

@ -57,7 +57,10 @@ namespace Squidex.Domain.Apps.Entities.Contents
var id = (await arguments[1].Expression.EvaluateAsync(context)).ToStringValue(); var id = (await arguments[1].Expression.EvaluateAsync(context)).ToStringValue();
var references = await contentQueryService.QueryAsync(appContext, new List<DomainId> { id }); var domainId = DomainId.Create(id);
var domainIds = new List<DomainId> { domainId };
var references = await contentQueryService.QueryAsync(appContext, domainIds);
var reference = references.FirstOrDefault(); var reference = references.FirstOrDefault();
if (reference != null) if (reference != null)

2
backend/src/Squidex.Domain.Apps.Entities/Q.cs

@ -67,7 +67,7 @@ namespace Squidex.Domain.Apps.Entities
foreach (var id in ids.Split(',')) foreach (var id in ids.Split(','))
{ {
idsList.Add(id); idsList.Add(DomainId.Create(id));
} }
c.Ids = idsList; c.Ids = idsList;

2
backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerGrain.cs

@ -143,7 +143,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Runner
{ {
currentReminder = await RegisterOrUpdateReminder("KeepAlive", TimeSpan.Zero, TimeSpan.FromMinutes(2)); currentReminder = await RegisterOrUpdateReminder("KeepAlive", TimeSpan.Zero, TimeSpan.FromMinutes(2));
var rules = await appProvider.GetRulesAsync(Key); var rules = await appProvider.GetRulesAsync(DomainId.Create(Key));
var rule = rules.Find(x => x.Id == job.RuleId); var rule = rules.Find(x => x.Id == job.RuleId);

27
backend/src/Squidex.Infrastructure.MongoDb/MongoDb/MongoEntity.cs

@ -1,27 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using MongoDB.Bson.Serialization.Attributes;
using NodaTime;
namespace Squidex.Infrastructure.MongoDb
{
public abstract class MongoEntity
{
[BsonId]
[BsonElement]
public string DocumentId { get; set; }
[BsonRequired]
[BsonElement]
public Instant Created { get; set; }
[BsonRequired]
[BsonElement]
public Instant LastModified { get; set; }
}
}

2
backend/src/Squidex.Infrastructure/Commands/DomainObject.cs

@ -33,7 +33,7 @@ namespace Squidex.Infrastructure.Commands
protected override void OnSetup() protected override void OnSetup()
{ {
persistence = store.WithSnapshotsAndEventSourcing(GetType(), UniqueId.ToString(), new HandleSnapshot<T>(ApplySnapshot), x => ApplyEvent(x, true)); persistence = store.WithSnapshotsAndEventSourcing(GetType(), UniqueId, new HandleSnapshot<T>(ApplySnapshot), x => ApplyEvent(x, true));
} }
protected sealed override bool ApplyEvent(Envelope<IEvent> @event, bool isLoading) protected sealed override bool ApplyEvent(Envelope<IEvent> @event, bool isLoading)

2
backend/src/Squidex.Infrastructure/Commands/DomainObjectGrain.cs

@ -35,7 +35,7 @@ namespace Squidex.Infrastructure.Commands
protected override Task OnActivateAsync(string key) protected override Task OnActivateAsync(string key)
{ {
domainObject.Setup(key); domainObject.Setup(DomainId.Create(key));
return base.OnActivateAsync(key); return base.OnActivateAsync(key);
} }

6
backend/src/Squidex.Infrastructure/Commands/LogSnapshotDomainObject.cs

@ -35,7 +35,7 @@ namespace Squidex.Infrastructure.Commands
protected override void OnSetup() protected override void OnSetup()
{ {
persistence = store.WithEventSourcing(GetType(), UniqueId.ToString(), x => ApplyEvent(x, true)); persistence = store.WithEventSourcing(GetType(), UniqueId, x => ApplyEvent(x, true));
} }
public T GetSnapshot(long version) public T GetSnapshot(long version)
@ -82,7 +82,7 @@ namespace Squidex.Infrastructure.Commands
var persistedSnapshots = store.GetSnapshotStore<T>(); var persistedSnapshots = store.GetSnapshotStore<T>();
await persistence.WriteEventsAsync(newEvents); await persistence.WriteEventsAsync(newEvents);
await persistedSnapshots.WriteAsync(UniqueId.ToString(), Snapshot, previousVersion, Snapshot.Version); await persistedSnapshots.WriteAsync(UniqueId, Snapshot, previousVersion, Snapshot.Version);
} }
} }
@ -107,7 +107,7 @@ namespace Squidex.Infrastructure.Commands
{ {
var persistedSnapshots = store.GetSnapshotStore<T>(); var persistedSnapshots = store.GetSnapshotStore<T>();
await persistedSnapshots.WriteAsync(UniqueId.ToString(), Snapshot, EtagVersion.Any, Snapshot.Version); await persistedSnapshots.WriteAsync(UniqueId, Snapshot, EtagVersion.Any, Snapshot.Version);
} }
} }

10
backend/src/Squidex.Infrastructure/DomainId.cs

@ -79,16 +79,6 @@ namespace Squidex.Infrastructure
return string.Compare(id, other.id, StringComparison.Ordinal); return string.Compare(id, other.id, StringComparison.Ordinal);
} }
public static implicit operator DomainId(string value)
{
return Create(value);
}
public static implicit operator DomainId(Guid value)
{
return Create(value);
}
public static bool operator ==(DomainId lhs, DomainId rhs) public static bool operator ==(DomainId lhs, DomainId rhs)
{ {
return lhs.Equals(rhs); return lhs.Equals(rhs);

2
backend/src/Squidex.Infrastructure/DomainIdTypeConverter.cs

@ -15,7 +15,7 @@ namespace Squidex.Infrastructure
{ {
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{ {
return sourceType == typeof(string) && sourceType == typeof(Guid); return sourceType == typeof(string) || sourceType == typeof(Guid);
} }
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)

2
backend/src/Squidex.Infrastructure/EventSourcing/EnvelopeExtensions.cs

@ -53,7 +53,7 @@ namespace Squidex.Infrastructure.EventSourcing
public static DomainId AggregateId(this EnvelopeHeaders headers) public static DomainId AggregateId(this EnvelopeHeaders headers)
{ {
return headers.GetString(CommonHeaders.AggregateId); return DomainId.Create(headers.GetString(CommonHeaders.AggregateId));
} }
public static Envelope<T> SetAggregateId<T>(this Envelope<T> envelope, DomainId value) where T : class, IEvent public static Envelope<T> SetAggregateId<T>(this Envelope<T> envelope, DomainId value) where T : class, IEvent

4
backend/src/Squidex.Infrastructure/Json/Newtonsoft/NamedDomainIdConverter.cs

@ -25,7 +25,7 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
if (!NamedId<DomainId>.TryParse(value, Parser, out var result)) if (!NamedId<DomainId>.TryParse(value, Parser, out var result))
{ {
throw new JsonException("Named id must have at least 2 parts divided by commata."); throw new JsonException("Named id must have at least 2 parts divided by comma.");
} }
return result; return result;
@ -33,7 +33,7 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
private static bool ParseString(ReadOnlySpan<char> value, out DomainId result) private static bool ParseString(ReadOnlySpan<char> value, out DomainId result)
{ {
result = new string(value); result = DomainId.Create(new string(value));
return true; return true;
} }

4
backend/src/Squidex.Web/Pipeline/SchemaResolver.cs

@ -60,7 +60,9 @@ namespace Squidex.Web.Pipeline
if (Guid.TryParse(schemaIdOrName, out var guid)) if (Guid.TryParse(schemaIdOrName, out var guid))
{ {
return appProvider.GetSchemaAsync(appId, guid, false, canCache); var schemaId = DomainId.Create(guid);
return appProvider.GetSchemaAsync(appId, schemaId, false, canCache);
} }
else else
{ {

5
backend/src/Squidex/Areas/Api/Controllers/Apps/AppPatternsController.cs

@ -11,6 +11,7 @@ using Microsoft.Net.Http.Headers;
using Squidex.Areas.Api.Controllers.Apps.Models; using Squidex.Areas.Api.Controllers.Apps.Models;
using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Shared; using Squidex.Shared;
using Squidex.Web; using Squidex.Web;
@ -96,7 +97,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(PatternsDto), 200)] [ProducesResponseType(typeof(PatternsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppPatternsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppPatternsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutPattern(string app, string id, [FromBody] UpdatePatternDto request) public async Task<IActionResult> PutPattern(string app, DomainId id, [FromBody] UpdatePatternDto request)
{ {
var command = request.ToUpdateCommand(id); var command = request.ToUpdateCommand(id);
@ -122,7 +123,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(PatternsDto), 200)] [ProducesResponseType(typeof(PatternsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppPatternsDelete)] [ApiPermissionOrAnonymous(Permissions.AppPatternsDelete)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DeletePattern(string app, string id) public async Task<IActionResult> DeletePattern(string app, DomainId id)
{ {
var command = new DeletePattern { PatternId = id }; var command = new DeletePattern { PatternId = id };

5
backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs

@ -12,6 +12,7 @@ using Squidex.Areas.Api.Controllers.Apps.Models;
using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Shared; using Squidex.Shared;
using Squidex.Web; using Squidex.Web;
@ -97,7 +98,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(WorkflowsDto), 200)] [ProducesResponseType(typeof(WorkflowsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutWorkflow(string app, string id, [FromBody] UpdateWorkflowDto request) public async Task<IActionResult> PutWorkflow(string app, DomainId id, [FromBody] UpdateWorkflowDto request)
{ {
var command = request.ToCommand(id); var command = request.ToCommand(id);
@ -120,7 +121,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(WorkflowsDto), 200)] [ProducesResponseType(typeof(WorkflowsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DeleteWorkflow(string app, string id) public async Task<IActionResult> DeleteWorkflow(string app, DomainId id)
{ {
var command = new DeleteWorkflow { WorkflowId = id }; var command = new DeleteWorkflow { WorkflowId = id };

3
backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdatePatternDto.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Validation; using Squidex.Infrastructure.Validation;
@ -35,7 +36,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
return SimpleMapper.Map(this, new AddPattern()); return SimpleMapper.Map(this, new AddPattern());
} }
public UpdatePattern ToUpdateCommand(string id) public UpdatePattern ToUpdateCommand(DomainId id)
{ {
return SimpleMapper.Map(this, new UpdatePattern { PatternId = id }); return SimpleMapper.Map(this, new UpdatePattern { PatternId = id });
} }

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

@ -38,7 +38,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
[LocalizedRequired] [LocalizedRequired]
public Status Initial { get; set; } public Status Initial { get; set; }
public UpdateWorkflow ToCommand(string id) public UpdateWorkflow ToCommand(DomainId id)
{ {
var workflow = new Workflow( var workflow = new Workflow(
Initial, Initial,

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

@ -73,7 +73,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> GetAssetContentBySlug(string app, string idOrSlug, [FromQuery] AssetContentQueryDto queries, string? more = null) public async Task<IActionResult> GetAssetContentBySlug(string app, string idOrSlug, [FromQuery] AssetContentQueryDto queries, string? more = null)
{ {
var asset = await assetRepository.FindAssetAsync(AppId, idOrSlug); var asset = await assetRepository.FindAssetAsync(AppId, DomainId.Create(idOrSlug));
if (asset == null) if (asset == null)
{ {
@ -99,7 +99,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ApiCosts(0.5)] [ApiCosts(0.5)]
[AllowAnonymous] [AllowAnonymous]
[Obsolete] [Obsolete]
public async Task<IActionResult> GetAssetContent(string id, [FromQuery] AssetContentQueryDto queries) public async Task<IActionResult> GetAssetContent(DomainId id, [FromQuery] AssetContentQueryDto queries)
{ {
var asset = await assetRepository.FindAssetAsync(id); var asset = await assetRepository.FindAssetAsync(id);

17
backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs

@ -11,6 +11,7 @@ using Microsoft.Net.Http.Headers;
using Squidex.Areas.Api.Controllers.Assets.Models; using Squidex.Areas.Api.Controllers.Assets.Models;
using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Tasks; using Squidex.Infrastructure.Tasks;
using Squidex.Shared; using Squidex.Shared;
@ -49,11 +50,13 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ProducesResponseType(typeof(AssetsDto), 200)] [ProducesResponseType(typeof(AssetsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)] [ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> GetAssetFolders(string app, [FromQuery] string parentId) public async Task<IActionResult> GetAssetFolders(string app, [FromQuery] DomainId parentId)
{ {
var (folders, path) = await AsyncHelper.WhenAll( var (folders, path) =
assetQuery.QueryAssetFoldersAsync(Context, parentId), await AsyncHelper.WhenAll(
assetQuery.FindAssetFolderAsync(Context.App.Id, parentId)); assetQuery.QueryAssetFoldersAsync(Context, parentId),
assetQuery.FindAssetFolderAsync(Context.App.Id, parentId)
);
var response = Deferred.Response(() => var response = Deferred.Response(() =>
{ {
@ -106,7 +109,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit] [AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutAssetFolder(string app, string id, [FromBody] RenameAssetFolderDto request) public async Task<IActionResult> PutAssetFolder(string app, DomainId id, [FromBody] RenameAssetFolderDto request)
{ {
var command = request.ToCommand(id); var command = request.ToCommand(id);
@ -131,7 +134,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit] [AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutAssetFolderParent(string app, string id, [FromBody] MoveAssetItemDto request) public async Task<IActionResult> PutAssetFolderParent(string app, DomainId id, [FromBody] MoveAssetItemDto request)
{ {
var command = request.ToFolderCommand(id); var command = request.ToFolderCommand(id);
@ -153,7 +156,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/folders/{id}/", Order = -1)] [Route("apps/{app}/assets/folders/{id}/", Order = -1)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DeleteAssetFolder(string app, string id) public async Task<IActionResult> DeleteAssetFolder(string app, DomainId id)
{ {
await CommandBus.PublishAsync(new DeleteAssetFolder { AssetFolderId = id }); await CommandBus.PublishAsync(new DeleteAssetFolder { AssetFolderId = id });

19
backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs

@ -16,6 +16,7 @@ using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Entities.Apps.Plans; using Squidex.Domain.Apps.Entities.Apps.Plans;
using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets; using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.Translations;
@ -96,7 +97,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> GetAssets(string app, [FromQuery] string? parentId, [FromQuery] string? ids = null, [FromQuery] string? q = null) public async Task<IActionResult> GetAssets(string app, [FromQuery] string? parentId, [FromQuery] string? ids = null, [FromQuery] string? q = null)
{ {
var assets = await assetQuery.QueryAsync(Context, parentId!, CreateQuery(ids, q)); var assets = await assetQuery.QueryAsync(Context, DomainId.CreateNullable(parentId), CreateQuery(ids, q));
var response = Deferred.Response(() => var response = Deferred.Response(() =>
{ {
@ -149,7 +150,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ProducesResponseType(typeof(AssetDto), 200)] [ProducesResponseType(typeof(AssetDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)] [ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> GetAsset(string app, string id) public async Task<IActionResult> GetAsset(string app, DomainId id)
{ {
var asset = await assetQuery.FindAssetAsync(Context, id); var asset = await assetQuery.FindAssetAsync(Context, id);
@ -188,15 +189,15 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit] [AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsCreate)] [ApiPermissionOrAnonymous(Permissions.AppAssetsCreate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PostAsset(string app, [FromQuery] string parentId, IFormFile file, [FromQuery] string? id = null, [FromQuery] bool duplicate = false) public async Task<IActionResult> PostAsset(string app, [FromQuery] DomainId parentId, IFormFile file, [FromQuery] DomainId? id = null, [FromQuery] bool duplicate = false)
{ {
var assetFile = await CheckAssetFileAsync(file); var assetFile = await CheckAssetFileAsync(file);
var command = new CreateAsset { File = assetFile, ParentId = parentId, Duplicate = duplicate }; var command = new CreateAsset { File = assetFile, ParentId = parentId, Duplicate = duplicate };
if (!string.IsNullOrWhiteSpace(id)) if (id != null && id.Value != default && !string.IsNullOrWhiteSpace(id.Value.ToString()))
{ {
command.AssetId = id; command.AssetId = id.Value;
} }
var response = await InvokeCommandAsync(command); var response = await InvokeCommandAsync(command);
@ -223,7 +224,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ProducesResponseType(typeof(AssetDto), 200)] [ProducesResponseType(typeof(AssetDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpload)] [ApiPermissionOrAnonymous(Permissions.AppAssetsUpload)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutAssetContent(string app, string id, IFormFile file) public async Task<IActionResult> PutAssetContent(string app, DomainId id, IFormFile file)
{ {
var assetFile = await CheckAssetFileAsync(file); var assetFile = await CheckAssetFileAsync(file);
@ -251,7 +252,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit] [AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutAsset(string app, string id, [FromBody] AnnotateAssetDto request) public async Task<IActionResult> PutAsset(string app, DomainId id, [FromBody] AnnotateAssetDto request)
{ {
var command = request.ToCommand(id); var command = request.ToCommand(id);
@ -276,7 +277,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit] [AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutAssetParent(string app, string id, [FromBody] MoveAssetItemDto request) public async Task<IActionResult> PutAssetParent(string app, DomainId id, [FromBody] MoveAssetItemDto request)
{ {
var command = request.ToCommand(id); var command = request.ToCommand(id);
@ -299,7 +300,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/{id}/")] [Route("apps/{app}/assets/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppAssetsDelete)] [ApiPermissionOrAnonymous(Permissions.AppAssetsDelete)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DeleteAsset(string app, string id, [FromQuery] bool checkReferrers = false) public async Task<IActionResult> DeleteAsset(string app, DomainId id, [FromQuery] bool checkReferrers = false)
{ {
await CommandBus.PublishAsync(new DeleteAsset { AssetId = id, CheckReferrers = checkReferrers }); await CommandBus.PublishAsync(new DeleteAsset { AssetId = id, CheckReferrers = checkReferrers });

3
backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AnnotateAssetDto.cs

@ -8,6 +8,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Squidex.Domain.Apps.Core.Assets; using Squidex.Domain.Apps.Core.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
namespace Squidex.Areas.Api.Controllers.Assets.Models namespace Squidex.Areas.Api.Controllers.Assets.Models
@ -39,7 +40,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models
/// </summary> /// </summary>
public AssetMetadata? Metadata { get; set; } public AssetMetadata? Metadata { get; set; }
public AnnotateAsset ToCommand(string id) public AnnotateAsset ToCommand(DomainId id)
{ {
return SimpleMapper.Map(this, new AnnotateAsset { AssetId = id }); return SimpleMapper.Map(this, new AnnotateAsset { AssetId = id });
} }

2
backend/src/Squidex/Areas/Api/Controllers/Assets/Models/MoveAssetItemDto.cs

@ -22,7 +22,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models
return new MoveAsset { AssetId = id, ParentId = ParentId }; return new MoveAsset { AssetId = id, ParentId = ParentId };
} }
public MoveAssetFolder ToFolderCommand(string id) public MoveAssetFolder ToFolderCommand(DomainId id)
{ {
return new MoveAssetFolder { AssetFolderId = id, ParentId = ParentId }; return new MoveAssetFolder { AssetFolderId = id, ParentId = ParentId };
} }

3
backend/src/Squidex/Areas/Api/Controllers/Assets/Models/RenameAssetFolderDto.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Validation; using Squidex.Infrastructure.Validation;
@ -19,7 +20,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models
[LocalizedRequired] [LocalizedRequired]
public string FolderName { get; set; } public string FolderName { get; set; }
public RenameAssetFolder ToCommand(string id) public RenameAssetFolder ToCommand(DomainId id)
{ {
return SimpleMapper.Map(this, new RenameAssetFolder { AssetFolderId = id }); return SimpleMapper.Map(this, new RenameAssetFolder { AssetFolderId = id });
} }

3
backend/src/Squidex/Areas/Api/Controllers/Backups/BackupContentController.cs

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Squidex.Domain.Apps.Entities.Backup; using Squidex.Domain.Apps.Entities.Backup;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Web; using Squidex.Web;
@ -47,7 +48,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[ProducesResponseType(typeof(FileResult), 200)] [ProducesResponseType(typeof(FileResult), 200)]
[ApiCosts(0)] [ApiCosts(0)]
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> GetBackupContent(string app, string id) public async Task<IActionResult> GetBackupContent(string app, DomainId id)
{ {
var backup = await backupservice.GetBackupAsync(AppId, id); var backup = await backupservice.GetBackupAsync(AppId, id);

3
backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Squidex.Areas.Api.Controllers.Backups.Models; using Squidex.Areas.Api.Controllers.Backups.Models;
using Squidex.Domain.Apps.Entities.Backup; using Squidex.Domain.Apps.Entities.Backup;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Security; using Squidex.Infrastructure.Security;
using Squidex.Infrastructure.Tasks; using Squidex.Infrastructure.Tasks;
@ -88,7 +89,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[ProducesResponseType(typeof(List<BackupJobDto>), 200)] [ProducesResponseType(typeof(List<BackupJobDto>), 200)]
[ApiPermissionOrAnonymous(Permissions.AppBackupsDelete)] [ApiPermissionOrAnonymous(Permissions.AppBackupsDelete)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> DeleteBackup(string app, string id) public async Task<IActionResult> DeleteBackup(string app, DomainId id)
{ {
await backupService.DeleteBackupAsync(AppId, id); await backupService.DeleteBackupAsync(AppId, id);

20
backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs

@ -50,7 +50,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
[ProducesResponseType(typeof(CommentsDto), 200)] [ProducesResponseType(typeof(CommentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppCommentsRead)] [ApiPermissionOrAnonymous(Permissions.AppCommentsRead)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> GetComments(string app, string commentsId, [FromQuery] long version = EtagVersion.Any) public async Task<IActionResult> GetComments(string app, DomainId commentsId, [FromQuery] long version = EtagVersion.Any)
{ {
var result = await commentsLoader.GetCommentsAsync(commentsId, version); var result = await commentsLoader.GetCommentsAsync(commentsId, version);
@ -80,7 +80,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
[ProducesResponseType(typeof(CommentDto), 201)] [ProducesResponseType(typeof(CommentDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppCommentsCreate)] [ApiPermissionOrAnonymous(Permissions.AppCommentsCreate)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> PostComment(string app, string commentsId, [FromBody] UpsertCommentDto request) public async Task<IActionResult> PostComment(string app, DomainId commentsId, [FromBody] UpsertCommentDto request)
{ {
var command = request.ToCreateCommand(commentsId); var command = request.ToCreateCommand(commentsId);
@ -107,9 +107,11 @@ namespace Squidex.Areas.Api.Controllers.Comments
[Route("apps/{app}/comments/{commentsId}/{commentId}")] [Route("apps/{app}/comments/{commentsId}/{commentId}")]
[ApiPermissionOrAnonymous(Permissions.AppCommentsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppCommentsUpdate)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> PutComment(string app, string commentsId, string commentId, [FromBody] UpsertCommentDto request) public async Task<IActionResult> PutComment(string app, DomainId commentsId, DomainId commentId, [FromBody] UpsertCommentDto request)
{ {
await CommandBus.PublishAsync(request.ToUpdateComment(commentsId, commentId)); var command = request.ToUpdateComment(commentsId, commentId);
await CommandBus.PublishAsync(command);
return NoContent(); return NoContent();
} }
@ -128,13 +130,11 @@ namespace Squidex.Areas.Api.Controllers.Comments
[Route("apps/{app}/comments/{commentsId}/{commentId}")] [Route("apps/{app}/comments/{commentsId}/{commentId}")]
[ApiPermissionOrAnonymous(Permissions.AppCommentsDelete)] [ApiPermissionOrAnonymous(Permissions.AppCommentsDelete)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> DeleteComment(string app, string commentsId, string commentId) public async Task<IActionResult> DeleteComment(string app, DomainId commentsId, DomainId commentId)
{ {
await CommandBus.PublishAsync(new DeleteComment var command = new DeleteComment { CommentsId = commentsId, CommentId = commentId };
{
CommentsId = commentsId, await CommandBus.PublishAsync(command);
CommentId = commentId
});
return NoContent(); return NoContent();
} }

5
backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs

@ -7,6 +7,7 @@
using System; using System;
using Squidex.Domain.Apps.Entities.Comments.Commands; using Squidex.Domain.Apps.Entities.Comments.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Validation; using Squidex.Infrastructure.Validation;
@ -25,12 +26,12 @@ namespace Squidex.Areas.Api.Controllers.Comments.Models
/// </summary> /// </summary>
public Uri? Url { get; set; } public Uri? Url { get; set; }
public CreateComment ToCreateCommand(string commentsId) public CreateComment ToCreateCommand(DomainId commentsId)
{ {
return SimpleMapper.Map(this, new CreateComment { CommentsId = commentsId }); return SimpleMapper.Map(this, new CreateComment { CommentsId = commentsId });
} }
public UpdateComment ToUpdateComment(string commentsId, string commentId) public UpdateComment ToUpdateComment(DomainId commentsId, DomainId commentId)
{ {
return SimpleMapper.Map(this, new UpdateComment { CommentsId = commentsId, CommentId = commentId }); return SimpleMapper.Map(this, new UpdateComment { CommentsId = commentsId, CommentId = commentId });
} }

14
backend/src/Squidex/Areas/Api/Controllers/Comments/Notifications/UserNotificationsController.cs

@ -49,7 +49,7 @@ namespace Squidex.Areas.Api.Controllers.Comments.Notifications
[Route("users/{userId}/notifications")] [Route("users/{userId}/notifications")]
[ProducesResponseType(typeof(CommentsDto), 200)] [ProducesResponseType(typeof(CommentsDto), 200)]
[ApiPermission] [ApiPermission]
public async Task<IActionResult> GetNotifications(string userId, [FromQuery] long version = EtagVersion.Any) public async Task<IActionResult> GetNotifications(DomainId userId, [FromQuery] long version = EtagVersion.Any)
{ {
CheckPermissions(userId); CheckPermissions(userId);
@ -77,23 +77,25 @@ namespace Squidex.Areas.Api.Controllers.Comments.Notifications
[HttpDelete] [HttpDelete]
[Route("users/{userId}/notifications/{commentId}")] [Route("users/{userId}/notifications/{commentId}")]
[ApiPermission] [ApiPermission]
public async Task<IActionResult> DeleteComment(string userId, string commentId) public async Task<IActionResult> DeleteComment(DomainId userId, DomainId commentId)
{ {
CheckPermissions(userId); CheckPermissions(userId);
await CommandBus.PublishAsync(new DeleteComment var commmand = new DeleteComment
{ {
AppId = NoApp, AppId = NoApp,
CommentsId = userId, CommentsId = userId,
CommentId = commentId CommentId = commentId
}); };
await CommandBus.PublishAsync(commmand);
return NoContent(); return NoContent();
} }
private void CheckPermissions(string userId) private void CheckPermissions(DomainId userId)
{ {
if (!string.Equals(userId, User.OpenIdSubject())) if (!string.Equals(userId.ToString(), User.OpenIdSubject()))
{ {
throw new DomainForbiddenException(T.Get("comments.noPermissions")); throw new DomainForbiddenException(T.Get("comments.noPermissions"));
} }

25
backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs

@ -14,6 +14,7 @@ using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Contents.GraphQL; using Squidex.Domain.Apps.Entities.Contents.GraphQL;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Shared; using Squidex.Shared;
using Squidex.Web; using Squidex.Web;
@ -275,7 +276,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous] [ApiPermissionOrAnonymous]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> GetContent(string app, string name, string id) public async Task<IActionResult> GetContent(string app, string name, DomainId id)
{ {
var content = await contentQuery.FindContentAsync(Context, name, id); var content = await contentQuery.FindContentAsync(Context, name, id);
@ -303,7 +304,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[Route("content/{app}/{name}/{id}/{version}/")] [Route("content/{app}/{name}/{id}/{version}/")]
[ApiPermissionOrAnonymous(Permissions.AppContentsRead)] [ApiPermissionOrAnonymous(Permissions.AppContentsRead)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> GetContentVersion(string app, string name, string id, int version) public async Task<IActionResult> GetContentVersion(string app, string name, DomainId id, int version)
{ {
var content = await contentQuery.FindContentAsync(Context, name, id, version); var content = await contentQuery.FindContentAsync(Context, name, id, version);
@ -333,13 +334,13 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 201)] [ProducesResponseType(typeof(ContentsDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppContentsCreate)] [ApiPermissionOrAnonymous(Permissions.AppContentsCreate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PostContent(string app, string name, [FromBody] NamedContentData request, [FromQuery] bool publish = false, [FromQuery] string? id = null) public async Task<IActionResult> PostContent(string app, string name, [FromBody] NamedContentData request, [FromQuery] bool publish = false, [FromQuery] DomainId? id = null)
{ {
var command = new CreateContent { Data = request.ToCleaned(), Publish = publish }; var command = new CreateContent { Data = request.ToCleaned(), Publish = publish };
if (!string.IsNullOrWhiteSpace(id)) if (id != null && id.Value != default && !string.IsNullOrWhiteSpace(id.Value.ToString()))
{ {
command.ContentId = id; command.ContentId = id.Value;
} }
var response = await InvokeCommandAsync(command); var response = await InvokeCommandAsync(command);
@ -430,7 +431,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PostContent(string app, string name, string id, [FromBody] NamedContentData request, [FromQuery] bool publish = false) public async Task<IActionResult> PostContent(string app, string name, DomainId id, [FromBody] NamedContentData request, [FromQuery] bool publish = false)
{ {
var command = new UpsertContent { ContentId = id, Data = request.ToCleaned(), Publish = publish }; var command = new UpsertContent { ContentId = id, Data = request.ToCleaned(), Publish = publish };
@ -459,7 +460,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutContent(string app, string name, string id, [FromBody] NamedContentData request) public async Task<IActionResult> PutContent(string app, string name, DomainId id, [FromBody] NamedContentData request)
{ {
var command = new UpdateContent { ContentId = id, Data = request.ToCleaned() }; var command = new UpdateContent { ContentId = id, Data = request.ToCleaned() };
@ -488,7 +489,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PatchContent(string app, string name, string id, [FromBody] NamedContentData request) public async Task<IActionResult> PatchContent(string app, string name, DomainId id, [FromBody] NamedContentData request)
{ {
var command = new PatchContent { ContentId = id, Data = request.ToCleaned() }; var command = new PatchContent { ContentId = id, Data = request.ToCleaned() };
@ -517,7 +518,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)] [ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutContentStatus(string app, string name, string id, ChangeStatusDto request) public async Task<IActionResult> PutContentStatus(string app, string name, DomainId id, ChangeStatusDto request)
{ {
var command = request.ToCommand(id); var command = request.ToCommand(id);
@ -544,7 +545,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsVersionCreate)] [ApiPermissionOrAnonymous(Permissions.AppContentsVersionCreate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> CreateDraft(string app, string name, string id) public async Task<IActionResult> CreateDraft(string app, string name, DomainId id)
{ {
var command = new CreateContentDraft { ContentId = id }; var command = new CreateContentDraft { ContentId = id };
@ -571,7 +572,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsDelete)] [ApiPermissionOrAnonymous(Permissions.AppContentsDelete)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DeleteVersion(string app, string name, string id) public async Task<IActionResult> DeleteVersion(string app, string name, DomainId id)
{ {
var command = new DeleteContentDraft { ContentId = id }; var command = new DeleteContentDraft { ContentId = id };
@ -598,7 +599,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[Route("content/{app}/{name}/{id}/")] [Route("content/{app}/{name}/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppContentsDelete)] [ApiPermissionOrAnonymous(Permissions.AppContentsDelete)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DeleteContent(string app, string name, string id, [FromQuery] bool checkReferrers = false) public async Task<IActionResult> DeleteContent(string app, string name, DomainId id, [FromQuery] bool checkReferrers = false)
{ {
var command = new DeleteContent { ContentId = id, CheckReferrers = checkReferrers }; var command = new DeleteContent { ContentId = id, CheckReferrers = checkReferrers };

3
backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ChangeStatusDto.cs

@ -8,6 +8,7 @@
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Validation; using Squidex.Infrastructure.Validation;
namespace Squidex.Areas.Api.Controllers.Contents.Models namespace Squidex.Areas.Api.Controllers.Contents.Models
@ -25,7 +26,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models
/// </summary> /// </summary>
public Instant? DueTime { get; set; } public Instant? DueTime { get; set; }
public ChangeContentStatus ToCommand(string id) public ChangeContentStatus ToCommand(DomainId id)
{ {
return new ChangeContentStatus { ContentId = id, Status = Status, DueTime = DueTime }; return new ChangeContentStatus { ContentId = id, Status = Status, DueTime = DueTime };
} }

3
backend/src/Squidex/Areas/Api/Controllers/Rules/Models/UpdateRuleDto.cs

@ -8,6 +8,7 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Entities.Rules.Commands; using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Infrastructure;
namespace Squidex.Areas.Api.Controllers.Rules.Models namespace Squidex.Areas.Api.Controllers.Rules.Models
{ {
@ -29,7 +30,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
[JsonConverter(typeof(RuleActionConverter))] [JsonConverter(typeof(RuleActionConverter))]
public RuleAction Action { get; set; } public RuleAction Action { get; set; }
public UpdateRule ToCommand(string id) public UpdateRule ToCommand(DomainId id)
{ {
var command = new UpdateRule { RuleId = id, Action = Action, Name = Name }; var command = new UpdateRule { RuleId = id, Action = Action, Name = Name };

20
backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs

@ -159,7 +159,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleDto), 200)] [ProducesResponseType(typeof(RuleDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesUpdate)] [ApiPermissionOrAnonymous(Permissions.AppRulesUpdate)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutRule(string app, string id, [FromBody] UpdateRuleDto request) public async Task<IActionResult> PutRule(string app, DomainId id, [FromBody] UpdateRuleDto request)
{ {
var command = request.ToCommand(id); var command = request.ToCommand(id);
@ -182,7 +182,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleDto), 200)] [ProducesResponseType(typeof(RuleDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesDisable)] [ApiPermissionOrAnonymous(Permissions.AppRulesDisable)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> EnableRule(string app, string id) public async Task<IActionResult> EnableRule(string app, DomainId id)
{ {
var command = new EnableRule { RuleId = id }; var command = new EnableRule { RuleId = id };
@ -205,7 +205,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleDto), 200)] [ProducesResponseType(typeof(RuleDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesDisable)] [ApiPermissionOrAnonymous(Permissions.AppRulesDisable)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DisableRule(string app, string id) public async Task<IActionResult> DisableRule(string app, DomainId id)
{ {
var command = new DisableRule { RuleId = id }; var command = new DisableRule { RuleId = id };
@ -227,7 +227,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/{id}/trigger/")] [Route("apps/{app}/rules/{id}/trigger/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)] [ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> TriggerRule(string app, string id) public async Task<IActionResult> TriggerRule(string app, DomainId id)
{ {
var command = new TriggerRule { RuleId = id }; var command = new TriggerRule { RuleId = id };
@ -249,7 +249,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(204)] [ProducesResponseType(204)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)] [ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> PutRuleRun(string app, string id) public async Task<IActionResult> PutRuleRun(string app, DomainId id)
{ {
await ruleRunnerService.RunAsync(App.Id, id); await ruleRunnerService.RunAsync(App.Id, id);
@ -269,7 +269,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/{id}/")] [Route("apps/{app}/rules/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesDelete)] [ApiPermissionOrAnonymous(Permissions.AppRulesDelete)]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> DeleteRule(string app, string id) public async Task<IActionResult> DeleteRule(string app, DomainId id)
{ {
await CommandBus.PublishAsync(new DeleteRule { RuleId = id }); await CommandBus.PublishAsync(new DeleteRule { RuleId = id });
@ -292,9 +292,9 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleEventsDto), 200)] [ProducesResponseType(typeof(RuleEventsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesRead)] [ApiPermissionOrAnonymous(Permissions.AppRulesRead)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> GetEvents(string app, [FromQuery] string? ruleId = null, [FromQuery] int skip = 0, [FromQuery] int take = 20) public async Task<IActionResult> GetEvents(string app, [FromQuery] DomainId? ruleId = null, [FromQuery] int skip = 0, [FromQuery] int take = 20)
{ {
var ruleEvents = await ruleEventsRepository.QueryByAppAsync(AppId, DomainId.CreateNullable(ruleId), skip, take); var ruleEvents = await ruleEventsRepository.QueryByAppAsync(AppId, ruleId, skip, take);
var response = RuleEventsDto.FromRuleEvents(ruleEvents, Resources); var response = RuleEventsDto.FromRuleEvents(ruleEvents, Resources);
@ -314,7 +314,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/events/{id}/")] [Route("apps/{app}/rules/events/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)] [ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> PutEvent(string app, string id) public async Task<IActionResult> PutEvent(string app, DomainId id)
{ {
var ruleEvent = await ruleEventsRepository.FindAsync(id); var ruleEvent = await ruleEventsRepository.FindAsync(id);
@ -341,7 +341,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/events/{id}/")] [Route("apps/{app}/rules/events/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)] [ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[ApiCosts(0)] [ApiCosts(0)]
public async Task<IActionResult> DeleteEvent(string app, string id) public async Task<IActionResult> DeleteEvent(string app, DomainId id)
{ {
var ruleEvent = await ruleEventsRepository.FindAsync(id); var ruleEvent = await ruleEventsRepository.FindAsync(id);

5
backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs

@ -13,6 +13,7 @@ using Squidex.Areas.Api.Controllers.Schemas.Models;
using Squidex.Domain.Apps.Entities; using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Shared; using Squidex.Shared;
using Squidex.Web; using Squidex.Web;
@ -80,7 +81,9 @@ namespace Squidex.Areas.Api.Controllers.Schemas
if (Guid.TryParse(name, out var guid)) if (Guid.TryParse(name, out var guid))
{ {
schema = await appProvider.GetSchemaAsync(AppId, guid, false); var schemaId = DomainId.Create(guid);
schema = await appProvider.GetSchemaAsync(AppId, schemaId, false);
} }
else else
{ {

3
backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs

@ -15,6 +15,7 @@ using Squidex.Areas.Api.Controllers.Statistics.Models;
using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Apps.Plans; using Squidex.Domain.Apps.Entities.Apps.Plans;
using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.UsageTracking; using Squidex.Infrastructure.UsageTracking;
using Squidex.Shared; using Squidex.Shared;
@ -170,7 +171,7 @@ namespace Squidex.Areas.Api.Controllers.Statistics
[ApiExplorerSettings(IgnoreApi = true)] [ApiExplorerSettings(IgnoreApi = true)]
public IActionResult GetLogFile(string token) public IActionResult GetLogFile(string token)
{ {
var appId = dataProtector.Unprotect(token); var appId = DomainId.Create(dataProtector.Unprotect(token));
var today = DateTime.UtcNow.Date; var today = DateTime.UtcNow.Date;

4
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterCompareTests.cs

@ -38,8 +38,8 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
private readonly NamedId<DomainId> appId = NamedId.Of(DomainId.NewGuid(), "my-app"); private readonly NamedId<DomainId> appId = NamedId.Of(DomainId.NewGuid(), "my-app");
private readonly NamedId<DomainId> schemaId = NamedId.Of(DomainId.NewGuid(), "my-schema"); private readonly NamedId<DomainId> schemaId = NamedId.Of(DomainId.NewGuid(), "my-schema");
private readonly Instant now = SystemClock.Instance.GetCurrentInstant(); private readonly Instant now = SystemClock.Instance.GetCurrentInstant();
private readonly DomainId contentId = Guid.NewGuid(); private readonly DomainId contentId = DomainId.NewGuid();
private readonly DomainId assetId = Guid.NewGuid(); private readonly DomainId assetId = DomainId.NewGuid();
private readonly RuleEventFormatter sut; private readonly RuleEventFormatter sut;
private class FakeContentResolver : IRuleEventFormatter private class FakeContentResolver : IRuleEventFormatter

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentsCommandMiddlewareTests.cs

@ -156,7 +156,7 @@ namespace Squidex.Domain.Apps.Entities.Comments
{ {
command.Actor = actor; command.Actor = actor;
command.AppId = appId; command.AppId = appId;
command.CommentsId = commentsId.ToString(); command.CommentsId = commentsId;
command.CommentId = commentId; command.CommentId = commentId;
return command; return command;

4
backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentsLoaderTests.cs

@ -26,7 +26,7 @@ namespace Squidex.Domain.Apps.Entities.Comments
[Fact] [Fact]
public async Task Should_get_comments_from_grain() public async Task Should_get_comments_from_grain()
{ {
var commentsId = DomainId.NewGuid().ToString(); var commentsId = DomainId.NewGuid();
var comments = new CommentsResult(); var comments = new CommentsResult();
var grain = A.Fake<ICommentsGrain>(); var grain = A.Fake<ICommentsGrain>();
@ -34,7 +34,7 @@ namespace Squidex.Domain.Apps.Entities.Comments
A.CallTo(() => grain.GetCommentsAsync(11)) A.CallTo(() => grain.GetCommentsAsync(11))
.Returns(comments); .Returns(comments);
A.CallTo(() => grainFactory.GetGrain<ICommentsGrain>(commentsId, null)) A.CallTo(() => grainFactory.GetGrain<ICommentsGrain>(commentsId.ToString(), null))
.Returns(grain); .Returns(grain);
var result = await sut.GetCommentsAsync(commentsId, 11); var result = await sut.GetCommentsAsync(commentsId, 11);

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs

@ -24,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
{ {
public class GraphQLMutationTests : GraphQLTestBase public class GraphQLMutationTests : GraphQLTestBase
{ {
private readonly Guid contentId = Guid.NewGuid(); private readonly DomainId contentId = DomainId.NewGuid();
private readonly IEnrichedContentEntity content; private readonly IEnrichedContentEntity content;
private readonly CommandContext commandContext = new CommandContext(new PatchContent(), A.Dummy<ICommandBus>()); private readonly CommandContext commandContext = new CommandContext(new PatchContent(), A.Dummy<ICommandBus>());

2
backend/tests/Squidex.Infrastructure.Tests/Commands/CommandContextTests.cs

@ -30,7 +30,7 @@ namespace Squidex.Infrastructure.Commands
Assert.Null(sut.PlainResult); Assert.Null(sut.PlainResult);
Assert.Null(sut.Result<string>()); Assert.Null(sut.Result<string>());
Assert.NotEqual(Guid.Empty, sut.ContextId); Assert.NotEqual(DomainId.Empty, sut.ContextId);
Assert.False(sut.IsCompleted); Assert.False(sut.IsCompleted);
} }

3
backend/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs

@ -34,9 +34,10 @@ namespace Squidex.Infrastructure.TestHelpers
ContractResolver = new ConverterContractResolver( ContractResolver = new ConverterContractResolver(
new ClaimsPrincipalConverter(), new ClaimsPrincipalConverter(),
new InstantConverter(), new DomainIdConverter(),
new EnvelopeHeadersConverter(), new EnvelopeHeadersConverter(),
new FilterConverter(), new FilterConverter(),
new InstantConverter(),
new JsonValueConverter(), new JsonValueConverter(),
new LanguageConverter(), new LanguageConverter(),
new NamedGuidIdConverter(), new NamedGuidIdConverter(),

2
backend/tests/Squidex.Web.Tests/CommandMiddlewares/EnrichWithSchemaIdCommandMiddlewareTests.cs

@ -77,7 +77,7 @@ namespace Squidex.Web.CommandMiddlewares
{ {
httpContext.Features.Set<ISchemaFeature>(new SchemaFeature(schemaId)); httpContext.Features.Set<ISchemaFeature>(new SchemaFeature(schemaId));
var command = new CreateSchema { SchemaId = Guid.NewGuid() }; var command = new CreateSchema { SchemaId = DomainId.NewGuid() };
var context = Ctx(command); var context = Ctx(command);
await sut.HandleAsync(context); await sut.HandleAsync(context);

24
backend/tests/Squidex.Web.Tests/Pipeline/CachingFilterTests.cs

@ -212,8 +212,8 @@ namespace Squidex.Web.Pipeline
[Fact] [Fact]
public async Task Should_append_surrogate_keys() public async Task Should_append_surrogate_keys()
{ {
var id1 = DomainId.NewGuid().ToString(); var id1 = DomainId.NewGuid();
var id2 = DomainId.NewGuid().ToString(); var id2 = DomainId.NewGuid();
cachingOptions.MaxSurrogateKeysSize = 100; cachingOptions.MaxSurrogateKeysSize = 100;
@ -231,8 +231,8 @@ namespace Squidex.Web.Pipeline
[Fact] [Fact]
public async Task Should_append_surrogate_keys_if_just_enough_space_for_one() public async Task Should_append_surrogate_keys_if_just_enough_space_for_one()
{ {
var id1 = DomainId.NewGuid().ToString(); var id1 = DomainId.NewGuid();
var id2 = DomainId.NewGuid().ToString(); var id2 = DomainId.NewGuid();
cachingOptions.MaxSurrogateKeysSize = 36; cachingOptions.MaxSurrogateKeysSize = 36;
@ -250,8 +250,8 @@ namespace Squidex.Web.Pipeline
[Fact] [Fact]
public async Task Should_not_append_surrogate_keys_if_maximum_is_exceeded() public async Task Should_not_append_surrogate_keys_if_maximum_is_exceeded()
{ {
var id1 = DomainId.NewGuid().ToString(); var id1 = DomainId.NewGuid();
var id2 = DomainId.NewGuid().ToString(); var id2 = DomainId.NewGuid();
cachingOptions.MaxSurrogateKeysSize = 20; cachingOptions.MaxSurrogateKeysSize = 20;
@ -269,8 +269,8 @@ namespace Squidex.Web.Pipeline
[Fact] [Fact]
public async Task Should_not_append_surrogate_keys_if_maximum_is_overriden() public async Task Should_not_append_surrogate_keys_if_maximum_is_overriden()
{ {
var id1 = DomainId.NewGuid().ToString(); var id1 = DomainId.NewGuid();
var id2 = DomainId.NewGuid().ToString(); var id2 = DomainId.NewGuid();
httpContext.Request.Headers[CachingManager.SurrogateKeySizeHeader] = "20"; httpContext.Request.Headers[CachingManager.SurrogateKeySizeHeader] = "20";
@ -288,8 +288,8 @@ namespace Squidex.Web.Pipeline
[Fact] [Fact]
public async Task Should_generate_etag_from_ids_and_versions() public async Task Should_generate_etag_from_ids_and_versions()
{ {
var id1 = DomainId.NewGuid().ToString(); var id1 = DomainId.NewGuid();
var id2 = DomainId.NewGuid().ToString(); var id2 = DomainId.NewGuid();
await sut.OnActionExecutionAsync(executingContext, () => await sut.OnActionExecutionAsync(executingContext, () =>
{ {
@ -306,8 +306,8 @@ namespace Squidex.Web.Pipeline
[Fact] [Fact]
public async Task Should_not_generate_etag_when_already_added() public async Task Should_not_generate_etag_when_already_added()
{ {
var id1 = DomainId.NewGuid().ToString(); var id1 = DomainId.NewGuid();
var id2 = DomainId.NewGuid().ToString(); var id2 = DomainId.NewGuid();
await sut.OnActionExecutionAsync(executingContext, () => await sut.OnActionExecutionAsync(executingContext, () =>
{ {

Loading…
Cancel
Save