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. 15
      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.CommentsId = contentEvent.Id.ToString();
ruleJob.CommentsId = contentEvent.Id;
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}'");
}
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))
{

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

@ -67,7 +67,7 @@ namespace Migrations.Migrations.MongoDb
var domainType = eventStream.Substring(0, indexOfType);
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}";
document["EventStream"] = newStreamName;

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

@ -111,7 +111,7 @@ namespace Migrations.Migrations.MongoDb
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"] = 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.Rules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Infrastructure;
namespace Migrations.OldTriggers
{
@ -71,7 +72,9 @@ namespace Migrations.OldTriggers
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)
{
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)
{
result.Add(s.Value);
result.Add(DomainId.Create(s.Value));
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)
{
var result = urlGenerator.ContentUI(contentEvent.AppId, contentEvent.SchemaId, id.ToString());
var result = urlGenerator.ContentUI(contentEvent.AppId, contentEvent.SchemaId, id);
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>())
{
var documentId = DomainId.Combine(appId, id).ToString();
var documentId = DomainId.Combine(appId, id);
var assetFolderEntity =
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>())
{
var documentId = DomainId.Combine(appId, id).ToString();
var documentId = DomainId.Combine(appId, id);
var assetEntity =
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)
{
var documentId = DomainId.Combine(appId, id).ToString();
var documentId = DomainId.Combine(appId, id);
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));
var documentId = DomainId.Combine(schema.AppId, id).ToString();
var documentId = DomainId.Combine(schema.AppId, id);
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
{
public sealed class MongoRuleEventEntity : MongoEntity, IRuleEventEntity
[BsonIgnoreExtraElements]
public sealed class MongoRuleEventEntity : IRuleEventEntity
{
[BsonId]
[BsonElement]
public DomainId DocumentId { get; set; }
[BsonRequired]
[BsonElement]
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);
entity.DocumentId = job.Id.ToString();
entity.DocumentId = job.Id;
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(createApp.Actor.Identifier).AddAsync(createApp.AppId.ToString());
await Index(createApp.Actor.Identifier).AddAsync(createApp.AppId);
}
else
{
@ -253,7 +253,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
if (name.IsSlug())
{
var token = await index.ReserveAsync(command.AppId.ToString(), name);
var token = await index.ReserveAsync(command.AppId, name);
if (token == null)
{

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

@ -132,6 +132,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
try
{
var appId = DomainId.Create(Key);
using (var stream = backupArchiveLocation.OpenStream(job.Id))
{
using (var writer = await backupArchiveLocation.OpenWriterAsync(stream))
@ -140,7 +142,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
var userMapping = new UserMapping(actor);
var context = new BackupContext(Key, userMapping, writer);
var context = new BackupContext(appId, userMapping, writer);
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)
{
var previousAppId = appCreated.AppId.Id.ToString();
var previousAppId = appCreated.AppId.Id;
if (!string.IsNullOrWhiteSpace(CurrentJob.NewAppName))
{
@ -363,7 +363,9 @@ namespace Squidex.Domain.Apps.Entities.Backup
restoreContext.PreviousAppId.ToString(),
restoreContext.AppId.ToString());
@event.SetAggregateId(id);
var domainId = DomainId.Create(id);
@event.SetAggregateId(domainId);
}
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;
}
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);
}

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

@ -12,6 +12,6 @@ namespace Squidex.Domain.Apps.Entities.Comments
{
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)
{
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; }
static GraphQLModel()
{
ValueConverter.Register<string, DomainId>(DomainId.Create);
}
public GraphQLModel(IAppEntity app,
IEnumerable<ISchemaEntity> schemas,
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.Types;
using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Infrastructure;
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 =>
{
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 =>
{
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))
{
command.ContentId = contentId;
var id = DomainId.Create(contentId);
command.ContentId = id;
}
return command;
@ -236,7 +238,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
var contentData = GetContentData(c);
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 =>
{
var contentId = c.GetArgument<Guid>("id");
var contentId = c.GetArgument<DomainId>("id");
var contentData = GetContentData(c);
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 =>
{
var contentId = c.GetArgument<Guid>("id");
var contentId = c.GetArgument<DomainId>("id");
var contentData = GetContentData(c);
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 =>
{
var contentId = c.GetArgument<Guid>("id");
var contentId = c.GetArgument<DomainId>("id");
var contentStatus = new Status(c.GetArgument<string>("status"));
var contentDueTime = c.GetArgument<Instant?>("dueTime");
@ -381,7 +385,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
Name = "id",
Description = "The id of the content (usually GUID)",
DefaultValue = null,
ResolvedType = AllTypes.NonNullGuid
ResolvedType = AllTypes.NonNullString
},
new QueryArgument(AllTypes.None)
{
@ -396,7 +400,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
{
return ResolveAsync<EntitySavedResult>(appId, schemaId, c =>
{
var contentId = c.GetArgument<Guid>("id");
var contentId = c.GetArgument<DomainId>("id");
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))
{
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)

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 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();
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(','))
{
idsList.Add(id);
idsList.Add(DomainId.Create(id));
}
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));
var rules = await appProvider.GetRulesAsync(Key);
var rules = await appProvider.GetRulesAsync(DomainId.Create(Key));
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()
{
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)

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

@ -35,7 +35,7 @@ namespace Squidex.Infrastructure.Commands
protected override Task OnActivateAsync(string key)
{
domainObject.Setup(key);
domainObject.Setup(DomainId.Create(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()
{
persistence = store.WithEventSourcing(GetType(), UniqueId.ToString(), x => ApplyEvent(x, true));
persistence = store.WithEventSourcing(GetType(), UniqueId, x => ApplyEvent(x, true));
}
public T GetSnapshot(long version)
@ -82,7 +82,7 @@ namespace Squidex.Infrastructure.Commands
var persistedSnapshots = store.GetSnapshotStore<T>();
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>();
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);
}
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)
{
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)
{
return sourceType == typeof(string) && sourceType == typeof(Guid);
return sourceType == typeof(string) || sourceType == typeof(Guid);
}
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)
{
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

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))
{
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;
@ -33,7 +33,7 @@ namespace Squidex.Infrastructure.Json.Newtonsoft
private static bool ParseString(ReadOnlySpan<char> value, out DomainId result)
{
result = new string(value);
result = DomainId.Create(new string(value));
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))
{
return appProvider.GetSchemaAsync(appId, guid, false, canCache);
var schemaId = DomainId.Create(guid);
return appProvider.GetSchemaAsync(appId, schemaId, false, canCache);
}
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.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Shared;
using Squidex.Web;
@ -96,7 +97,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(PatternsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppPatternsUpdate)]
[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);
@ -122,7 +123,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(PatternsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppPatternsDelete)]
[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 };

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.Commands;
using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Shared;
using Squidex.Web;
@ -97,7 +98,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(WorkflowsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)]
[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);
@ -120,7 +121,7 @@ namespace Squidex.Areas.Api.Controllers.Apps
[ProducesResponseType(typeof(WorkflowsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppWorkflowsUpdate)]
[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 };

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

@ -6,6 +6,7 @@
// ==========================================================================
using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Validation;
@ -35,7 +36,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models
return SimpleMapper.Map(this, new AddPattern());
}
public UpdatePattern ToUpdateCommand(string id)
public UpdatePattern ToUpdateCommand(DomainId 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]
public Status Initial { get; set; }
public UpdateWorkflow ToCommand(string id)
public UpdateWorkflow ToCommand(DomainId id)
{
var workflow = new Workflow(
Initial,

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

@ -73,7 +73,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AllowAnonymous]
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)
{
@ -99,7 +99,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ApiCosts(0.5)]
[AllowAnonymous]
[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);

15
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.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Tasks;
using Squidex.Shared;
@ -49,11 +50,13 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ProducesResponseType(typeof(AssetsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[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) =
await AsyncHelper.WhenAll(
assetQuery.QueryAssetFoldersAsync(Context, parentId),
assetQuery.FindAssetFolderAsync(Context.App.Id, parentId));
assetQuery.FindAssetFolderAsync(Context.App.Id, parentId)
);
var response = Deferred.Response(() =>
{
@ -106,7 +109,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[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);
@ -131,7 +134,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[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);
@ -153,7 +156,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/folders/{id}/", Order = -1)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[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 });

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.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Translations;
@ -96,7 +97,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ApiCosts(1)]
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(() =>
{
@ -149,7 +150,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ProducesResponseType(typeof(AssetDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsRead)]
[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);
@ -188,15 +189,15 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsCreate)]
[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 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);
@ -223,7 +224,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[ProducesResponseType(typeof(AssetDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpload)]
[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);
@ -251,7 +252,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[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);
@ -276,7 +277,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[AssetRequestSizeLimit]
[ApiPermissionOrAnonymous(Permissions.AppAssetsUpdate)]
[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);
@ -299,7 +300,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
[Route("apps/{app}/assets/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppAssetsDelete)]
[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 });

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

@ -8,6 +8,7 @@
using System.Collections.Generic;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Areas.Api.Controllers.Assets.Models
@ -39,7 +40,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models
/// </summary>
public AssetMetadata? Metadata { get; set; }
public AnnotateAsset ToCommand(string id)
public AnnotateAsset ToCommand(DomainId 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 };
}
public MoveAssetFolder ToFolderCommand(string id)
public MoveAssetFolder ToFolderCommand(DomainId id)
{
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.Infrastructure;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Validation;
@ -19,7 +20,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models
[LocalizedRequired]
public string FolderName { get; set; }
public RenameAssetFolder ToCommand(string id)
public RenameAssetFolder ToCommand(DomainId 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.Mvc;
using Squidex.Domain.Apps.Entities.Backup;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Web;
@ -47,7 +48,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[ProducesResponseType(typeof(FileResult), 200)]
[ApiCosts(0)]
[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);

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

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Squidex.Areas.Api.Controllers.Backups.Models;
using Squidex.Domain.Apps.Entities.Backup;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Security;
using Squidex.Infrastructure.Tasks;
@ -88,7 +89,7 @@ namespace Squidex.Areas.Api.Controllers.Backups
[ProducesResponseType(typeof(List<BackupJobDto>), 200)]
[ApiPermissionOrAnonymous(Permissions.AppBackupsDelete)]
[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);

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

@ -50,7 +50,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
[ProducesResponseType(typeof(CommentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppCommentsRead)]
[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);
@ -80,7 +80,7 @@ namespace Squidex.Areas.Api.Controllers.Comments
[ProducesResponseType(typeof(CommentDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppCommentsCreate)]
[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);
@ -107,9 +107,11 @@ namespace Squidex.Areas.Api.Controllers.Comments
[Route("apps/{app}/comments/{commentsId}/{commentId}")]
[ApiPermissionOrAnonymous(Permissions.AppCommentsUpdate)]
[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();
}
@ -128,13 +130,11 @@ namespace Squidex.Areas.Api.Controllers.Comments
[Route("apps/{app}/comments/{commentsId}/{commentId}")]
[ApiPermissionOrAnonymous(Permissions.AppCommentsDelete)]
[ApiCosts(0)]
public async Task<IActionResult> DeleteComment(string app, string commentsId, string commentId)
{
await CommandBus.PublishAsync(new DeleteComment
public async Task<IActionResult> DeleteComment(string app, DomainId commentsId, DomainId commentId)
{
CommentsId = commentsId,
CommentId = commentId
});
var command = new DeleteComment { CommentsId = commentsId, CommentId = commentId };
await CommandBus.PublishAsync(command);
return NoContent();
}

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

@ -7,6 +7,7 @@
using System;
using Squidex.Domain.Apps.Entities.Comments.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Validation;
@ -25,12 +26,12 @@ namespace Squidex.Areas.Api.Controllers.Comments.Models
/// </summary>
public Uri? Url { get; set; }
public CreateComment ToCreateCommand(string commentsId)
public CreateComment ToCreateCommand(DomainId 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 });
}

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")]
[ProducesResponseType(typeof(CommentsDto), 200)]
[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);
@ -77,23 +77,25 @@ namespace Squidex.Areas.Api.Controllers.Comments.Notifications
[HttpDelete]
[Route("users/{userId}/notifications/{commentId}")]
[ApiPermission]
public async Task<IActionResult> DeleteComment(string userId, string commentId)
public async Task<IActionResult> DeleteComment(DomainId userId, DomainId commentId)
{
CheckPermissions(userId);
await CommandBus.PublishAsync(new DeleteComment
var commmand = new DeleteComment
{
AppId = NoApp,
CommentsId = userId,
CommentId = commentId
});
};
await CommandBus.PublishAsync(commmand);
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"));
}

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.Commands;
using Squidex.Domain.Apps.Entities.Contents.GraphQL;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Shared;
using Squidex.Web;
@ -275,7 +276,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous]
[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);
@ -303,7 +304,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[Route("content/{app}/{name}/{id}/{version}/")]
[ApiPermissionOrAnonymous(Permissions.AppContentsRead)]
[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);
@ -333,13 +334,13 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 201)]
[ApiPermissionOrAnonymous(Permissions.AppContentsCreate)]
[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 };
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);
@ -430,7 +431,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[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 };
@ -459,7 +460,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[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() };
@ -488,7 +489,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[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() };
@ -517,7 +518,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsUpdate)]
[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);
@ -544,7 +545,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsVersionCreate)]
[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 };
@ -571,7 +572,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppContentsDelete)]
[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 };
@ -598,7 +599,7 @@ namespace Squidex.Areas.Api.Controllers.Contents
[Route("content/{app}/{name}/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppContentsDelete)]
[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 };

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

@ -8,6 +8,7 @@
using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Validation;
namespace Squidex.Areas.Api.Controllers.Contents.Models
@ -25,7 +26,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models
/// </summary>
public Instant? DueTime { get; set; }
public ChangeContentStatus ToCommand(string id)
public ChangeContentStatus ToCommand(DomainId id)
{
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 Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Infrastructure;
namespace Squidex.Areas.Api.Controllers.Rules.Models
{
@ -29,7 +30,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
[JsonConverter(typeof(RuleActionConverter))]
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 };

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

@ -159,7 +159,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesUpdate)]
[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);
@ -182,7 +182,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesDisable)]
[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 };
@ -205,7 +205,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesDisable)]
[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 };
@ -227,7 +227,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/{id}/trigger/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[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 };
@ -249,7 +249,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(204)]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[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);
@ -269,7 +269,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesDelete)]
[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 });
@ -292,9 +292,9 @@ namespace Squidex.Areas.Api.Controllers.Rules
[ProducesResponseType(typeof(RuleEventsDto), 200)]
[ApiPermissionOrAnonymous(Permissions.AppRulesRead)]
[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);
@ -314,7 +314,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/events/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[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);
@ -341,7 +341,7 @@ namespace Squidex.Areas.Api.Controllers.Rules
[Route("apps/{app}/rules/events/{id}/")]
[ApiPermissionOrAnonymous(Permissions.AppRulesEvents)]
[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);

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.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Shared;
using Squidex.Web;
@ -80,7 +81,9 @@ namespace Squidex.Areas.Api.Controllers.Schemas
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
{

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.Plans;
using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.UsageTracking;
using Squidex.Shared;
@ -170,7 +171,7 @@ namespace Squidex.Areas.Api.Controllers.Statistics
[ApiExplorerSettings(IgnoreApi = true)]
public IActionResult GetLogFile(string token)
{
var appId = dataProtector.Unprotect(token);
var appId = DomainId.Create(dataProtector.Unprotect(token));
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> schemaId = NamedId.Of(DomainId.NewGuid(), "my-schema");
private readonly Instant now = SystemClock.Instance.GetCurrentInstant();
private readonly DomainId contentId = Guid.NewGuid();
private readonly DomainId assetId = Guid.NewGuid();
private readonly DomainId contentId = DomainId.NewGuid();
private readonly DomainId assetId = DomainId.NewGuid();
private readonly RuleEventFormatter sut;
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.AppId = appId;
command.CommentsId = commentsId.ToString();
command.CommentsId = commentsId;
command.CommentId = commentId;
return command;

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

@ -26,7 +26,7 @@ namespace Squidex.Domain.Apps.Entities.Comments
[Fact]
public async Task Should_get_comments_from_grain()
{
var commentsId = DomainId.NewGuid().ToString();
var commentsId = DomainId.NewGuid();
var comments = new CommentsResult();
var grain = A.Fake<ICommentsGrain>();
@ -34,7 +34,7 @@ namespace Squidex.Domain.Apps.Entities.Comments
A.CallTo(() => grain.GetCommentsAsync(11))
.Returns(comments);
A.CallTo(() => grainFactory.GetGrain<ICommentsGrain>(commentsId, null))
A.CallTo(() => grainFactory.GetGrain<ICommentsGrain>(commentsId.ToString(), null))
.Returns(grain);
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
{
private readonly Guid contentId = Guid.NewGuid();
private readonly DomainId contentId = DomainId.NewGuid();
private readonly IEnrichedContentEntity content;
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.Result<string>());
Assert.NotEqual(Guid.Empty, sut.ContextId);
Assert.NotEqual(DomainId.Empty, sut.ContextId);
Assert.False(sut.IsCompleted);
}

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

@ -34,9 +34,10 @@ namespace Squidex.Infrastructure.TestHelpers
ContractResolver = new ConverterContractResolver(
new ClaimsPrincipalConverter(),
new InstantConverter(),
new DomainIdConverter(),
new EnvelopeHeadersConverter(),
new FilterConverter(),
new InstantConverter(),
new JsonValueConverter(),
new LanguageConverter(),
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));
var command = new CreateSchema { SchemaId = Guid.NewGuid() };
var command = new CreateSchema { SchemaId = DomainId.NewGuid() };
var context = Ctx(command);
await sut.HandleAsync(context);

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

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

Loading…
Cancel
Save