diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 000000000..95317685c
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Qaisar Ahmad & Sebastian Stehle
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index a7e5bc73d..3fced5012 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,31 @@
-# Squidex
+
+
+# What is Squidex?
+
+Squidex is an open source headless CMS and content management hub. In contrast to an traditional CMS Squidex provides a rich API with OData filter support and Swagger Definitions. It is up to you to build you UI on top of it. It can be website, a native App or just another server.
+We built it on top of ASP.NET Core and CQRS and is tested for Windows and Linux on modern Browsers.
+
+[](https://gitter.im/squidex-cms/Lobby)
+
+Read the docs on [https://docs.squidex.io/](https://docs.squidex.io/) (work in progress) or just check out the code and play around.
+
+## Prerequisites
+
+* [Visual Studio Code](https://code.visualstudio.com/) or [Visual Studio 2017](https://www.visualstudio.com/vs/visual-studio-2017-rc/)
+* [Node.js](https://nodejs.org/en/)
+* [.NET Core SDK](https://www.microsoft.com/net/download/core#/current) (Already part of Visual Studio 2017)
+* [MongoDB](https://www.mongodb.com/)
+* [Redis](https://redis.io/download) (If you want to run Squidex on multiple hosts)
+
+## Contributors
+
+* [Qaisar Ahmad](http://www.qaisarahmad.com/) Interaction Designer, Pakistan
+* [Sebastian Stehle](https://github.com/SebastianStehle) Software Engineer, German (currently Sweden)
+
+## Contributing
+
+Please create issues to report bugs, suggest new functionalities, ask questions or just share your thoughts about the project. We will really appreciate your contribution, thanks.
+
+## Cloud Version
+
+Although Squidex is free we are also working on a Saas version on [Https://cloud.squidex.io](https://cloud.squidex.io) (More information coming soon). We have also have plans to sell a premium version with first class support and some exlusive features. But don't be afraid, our first priority is to deliver a state of the art, stable, fast and free content management hub to make the life for all developers a little bit easier.
diff --git a/Squidex.sln.DotSettings b/Squidex.sln.DotSettings
index 8404cbba9..0adccb11b 100644
--- a/Squidex.sln.DotSettings
+++ b/Squidex.sln.DotSettings
@@ -27,6 +27,7 @@
DO_NOT_SHOW
DO_NOT_SHOW
DO_NOT_SHOW
+ DO_NOT_SHOW
DO_NOT_SHOW
diff --git a/src/Squidex.Core/Identity/SquidexClaimTypes.cs b/src/Squidex.Core/Identity/SquidexClaimTypes.cs
index cd6c79d0f..bbdb0877a 100644
--- a/src/Squidex.Core/Identity/SquidexClaimTypes.cs
+++ b/src/Squidex.Core/Identity/SquidexClaimTypes.cs
@@ -10,10 +10,10 @@ namespace Squidex.Core.Identity
{
public class SquidexClaimTypes
{
- public const string SquidexDisplayName = "urn:squidex:name";
+ public static readonly string SquidexDisplayName = "urn:squidex:name";
- public const string SquidexPictureUrl = "urn:squidex:picture";
+ public static readonly string SquidexPictureUrl = "urn:squidex:picture";
- public const string Prefix = "urn:squidex:";
+ public static readonly string Prefix = "urn:squidex:";
}
}
diff --git a/src/Squidex.Core/Identity/SquidexRoles.cs b/src/Squidex.Core/Identity/SquidexRoles.cs
index d7e530c9c..ca0e9b3cb 100644
--- a/src/Squidex.Core/Identity/SquidexRoles.cs
+++ b/src/Squidex.Core/Identity/SquidexRoles.cs
@@ -10,12 +10,12 @@ namespace Squidex.Core.Identity
{
public static class SquidexRoles
{
- public const string Administrator = "ADMINISTRATOR";
+ public static readonly string Administrator = "ADMINISTRATOR";
- public const string AppOwner = "APP-OWNER";
+ public static readonly string AppOwner = "APP-OWNER";
- public const string AppEditor = "APP-EDITOR";
+ public static readonly string AppEditor = "APP-EDITOR";
- public const string AppDeveloper = "APP-DEVELOPER";
+ public static readonly string AppDeveloper = "APP-DEVELOPER";
}
}
diff --git a/src/Squidex.Core/Schemas/Json/JsonFieldModel.cs b/src/Squidex.Core/Schemas/Json/JsonFieldModel.cs
index 0394327f6..8697a94ea 100644
--- a/src/Squidex.Core/Schemas/Json/JsonFieldModel.cs
+++ b/src/Squidex.Core/Schemas/Json/JsonFieldModel.cs
@@ -10,12 +10,12 @@ namespace Squidex.Core.Schemas.Json
{
public sealed class JsonFieldModel
{
- public string Name;
+ public string Name { get; set; }
- public bool IsHidden;
+ public bool IsHidden { get; set; }
- public bool IsDisabled;
+ public bool IsDisabled { get; set; }
- public FieldProperties Properties;
+ public FieldProperties Properties { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Squidex.Core/Schemas/Json/JsonSchemaModel.cs b/src/Squidex.Core/Schemas/Json/JsonSchemaModel.cs
index b129a60da..3df33cfad 100644
--- a/src/Squidex.Core/Schemas/Json/JsonSchemaModel.cs
+++ b/src/Squidex.Core/Schemas/Json/JsonSchemaModel.cs
@@ -12,12 +12,12 @@ namespace Squidex.Core.Schemas.Json
{
public sealed class JsonSchemaModel
{
- public string Name;
+ public string Name { get; set; }
- public bool IsPublished;
+ public bool IsPublished { get; set; }
- public SchemaProperties Properties;
+ public SchemaProperties Properties { get; set; }
- public Dictionary Fields;
+ public Dictionary Fields { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Squidex.Core/Schemas/Json/SchemaJsonSerializer.cs b/src/Squidex.Core/Schemas/Json/SchemaJsonSerializer.cs
index 87146f14b..31dd33e94 100644
--- a/src/Squidex.Core/Schemas/Json/SchemaJsonSerializer.cs
+++ b/src/Squidex.Core/Schemas/Json/SchemaJsonSerializer.cs
@@ -74,7 +74,7 @@ namespace Squidex.Core.Schemas.Json
}
return field;
- }).ToDictionary(x => x.Id, x => x).ToImmutableDictionary();
+ }).ToImmutableDictionary(x => x.Id, x => x);
var schema =
new Schema(
diff --git a/src/Squidex.Core/Schemas/Schema.cs b/src/Squidex.Core/Schemas/Schema.cs
index 83994dea4..dba1f78b9 100644
--- a/src/Squidex.Core/Schemas/Schema.cs
+++ b/src/Squidex.Core/Schemas/Schema.cs
@@ -266,13 +266,7 @@ namespace Squidex.Core.Schemas
Guard.NotNull(errors, nameof(errors));
Guard.NotEmpty(languages, nameof(languages));
- foreach (var fieldData in data)
- {
- if (!fieldsByName.ContainsKey(fieldData.Key))
- {
- errors.Add(new ValidationError($"{fieldData.Key} is not a known field", fieldData.Key));
- }
- }
+ ValidateUnknownFields(data, errors);
foreach (var field in fieldsByName.Values)
{
@@ -281,35 +275,11 @@ namespace Squidex.Core.Schemas
if (field.RawProperties.IsLocalizable)
{
- foreach (var valueLanguage in fieldData.Keys)
- {
- if (!Language.TryGetLanguage(valueLanguage, out Language language))
- {
- fieldErrors.Add($"{field.Name} has an invalid language '{valueLanguage}'");
- }
- else if (!languages.Contains(language))
- {
- fieldErrors.Add($"{field.Name} has an unsupported language '{valueLanguage}'");
- }
- }
-
- foreach (var language in languages)
- {
- var value = fieldData.GetOrCreate(language.Iso2Code, k => JValue.CreateNull());
-
- await field.ValidateAsync(value, fieldErrors, language);
- }
+ await ValidateLocalizableFieldAsync(languages, fieldData, fieldErrors, field);
}
else
{
- if (fieldData.Keys.Any(x => x != Language.Invariant.Iso2Code))
- {
- fieldErrors.Add($"{field.Name} can only contain a single entry for invariant language ({Language.Invariant.Iso2Code})");
- }
-
- var value = fieldData.GetOrCreate(Language.Invariant.Iso2Code, k => JValue.CreateNull());
-
- await field.ValidateAsync(value, fieldErrors);
+ await ValidateNonLocalizableField(fieldData, fieldErrors, field);
}
foreach (var error in fieldErrors)
@@ -319,6 +289,51 @@ namespace Squidex.Core.Schemas
}
}
+ private void ValidateUnknownFields(ContentData data, IList errors)
+ {
+ foreach (var fieldData in data)
+ {
+ if (!fieldsByName.ContainsKey(fieldData.Key))
+ {
+ errors.Add(new ValidationError($"{fieldData.Key} is not a known field", fieldData.Key));
+ }
+ }
+ }
+
+ private static async Task ValidateLocalizableFieldAsync(HashSet languages, ContentFieldData fieldData, List fieldErrors, Field field)
+ {
+ foreach (var valueLanguage in fieldData.Keys)
+ {
+ if (!Language.TryGetLanguage(valueLanguage, out Language language))
+ {
+ fieldErrors.Add($"{field.Name} has an invalid language '{valueLanguage}'");
+ }
+ else if (!languages.Contains(language))
+ {
+ fieldErrors.Add($"{field.Name} has an unsupported language '{valueLanguage}'");
+ }
+ }
+
+ foreach (var language in languages)
+ {
+ var value = fieldData.GetOrCreate(language.Iso2Code, k => JValue.CreateNull());
+
+ await field.ValidateAsync(value, fieldErrors, language);
+ }
+ }
+
+ private static async Task ValidateNonLocalizableField(ContentFieldData fieldData, List fieldErrors, Field field)
+ {
+ if (fieldData.Keys.Any(x => x != Language.Invariant.Iso2Code))
+ {
+ fieldErrors.Add($"{field.Name} can only contain a single entry for invariant language ({Language.Invariant.Iso2Code})");
+ }
+
+ var value = fieldData.GetOrCreate(Language.Invariant.Iso2Code, k => JValue.CreateNull());
+
+ await field.ValidateAsync(value, fieldErrors);
+ }
+
public void Enrich(ContentData data, HashSet languages)
{
Guard.NotNull(data, nameof(data));
diff --git a/src/Squidex.Infrastructure.Redis/InfrastructureErrors.cs b/src/Squidex.Infrastructure.Redis/RedisInfrastructureErrors.cs
similarity index 89%
rename from src/Squidex.Infrastructure.Redis/InfrastructureErrors.cs
rename to src/Squidex.Infrastructure.Redis/RedisInfrastructureErrors.cs
index ee0ccdd6d..ca7ad3a3b 100644
--- a/src/Squidex.Infrastructure.Redis/InfrastructureErrors.cs
+++ b/src/Squidex.Infrastructure.Redis/RedisInfrastructureErrors.cs
@@ -1,5 +1,5 @@
// ==========================================================================
-// InfrastructureErrors.cs
+// RedisInfrastructureErrors.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
@@ -10,7 +10,7 @@ using Microsoft.Extensions.Logging;
namespace Squidex.Infrastructure.Redis
{
- public class InfrastructureErrors
+ public class RedisInfrastructureErrors
{
public static readonly EventId InvalidatingReceivedFailed = new EventId(50001, "InvalidingReceivedFailed");
diff --git a/src/Squidex.Infrastructure.Redis/RedisSubscription.cs b/src/Squidex.Infrastructure.Redis/RedisSubscription.cs
index b5db338b1..045858ce4 100644
--- a/src/Squidex.Infrastructure.Redis/RedisSubscription.cs
+++ b/src/Squidex.Infrastructure.Redis/RedisSubscription.cs
@@ -44,7 +44,7 @@ namespace Squidex.Infrastructure.Redis
}
catch (Exception ex)
{
- logger.LogError(InfrastructureErrors.InvalidatingReceivedFailed, ex, "Failed to send invalidation message {0}", token);
+ logger.LogError(RedisInfrastructureErrors.InvalidatingReceivedFailed, ex, "Failed to send invalidation message {0}", token);
}
}
@@ -78,7 +78,7 @@ namespace Squidex.Infrastructure.Redis
}
catch (Exception ex)
{
- logger.LogError(InfrastructureErrors.InvalidatingReceivedFailed, ex, "Failed to receive invalidation message.");
+ logger.LogError(RedisInfrastructureErrors.InvalidatingReceivedFailed, ex, "Failed to receive invalidation message.");
}
}
diff --git a/src/Squidex.Infrastructure/CQRS/CommonHeaders.cs b/src/Squidex.Infrastructure/CQRS/CommonHeaders.cs
index eecc2275d..9274e62e2 100644
--- a/src/Squidex.Infrastructure/CQRS/CommonHeaders.cs
+++ b/src/Squidex.Infrastructure/CQRS/CommonHeaders.cs
@@ -10,16 +10,16 @@ namespace Squidex.Infrastructure.CQRS
{
public sealed class CommonHeaders
{
- public const string AggregateId = "AggregateId";
+ public static readonly string AggregateId = "AggregateId";
- public const string CommitId = "CommitId";
+ public static readonly string CommitId = "CommitId";
- public const string EventId = "EventId";
+ public static readonly string EventId = "EventId";
- public const string EventNumber = "EventNumber";
+ public static readonly string EventNumber = "EventNumber";
- public const string Timestamp = "Timestamp";
+ public static readonly string Timestamp = "Timestamp";
- public const string Actor = "Actor";
+ public static readonly string Actor = "Actor";
}
}
diff --git a/src/Squidex.Infrastructure/Security/OpenIdClaims.cs b/src/Squidex.Infrastructure/Security/OpenIdClaims.cs
index 145fa02fd..1fe650780 100644
--- a/src/Squidex.Infrastructure/Security/OpenIdClaims.cs
+++ b/src/Squidex.Infrastructure/Security/OpenIdClaims.cs
@@ -13,31 +13,31 @@ namespace Squidex.Infrastructure.Security
///
/// Unique Identifier for the End-User at the Issuer.
///
- public const string Subject = "sub";
+ public static readonly string Subject = "sub";
///
/// The client id claim.
///
- public const string ClientId = "client_id";
+ public static readonly string ClientId = "client_id";
///
/// End-User's full name in displayable form including all name parts, possibly including titles and suffixes, ordered according to the End-User's locale and preferences.
///
- public const string Name = "name";
+ public static readonly string Name = "name";
///
/// Casual name of the End-User that may or may not be the same as the given_name. For instance, a nickname value of Mike might be returned alongside a given_name value of Michael.
///
- public const string NickName = "nickname";
+ public static readonly string NickName = "nickname";
///
/// Shorthand name by which the End-User wishes to be referred to at the
///
- public const string PreferredUserName = "preferred_username";
+ public static readonly string PreferredUserName = "preferred_username";
///
/// End-User's preferred e-mail address.
///
- public const string Email = "email";
+ public static readonly string Email = "email";
}
}
diff --git a/src/Squidex.Read.MongoDb/Utils/CollectionExtensions.cs b/src/Squidex.Read.MongoDb/Utils/MongoCollectionExtensions.cs
similarity index 97%
rename from src/Squidex.Read.MongoDb/Utils/CollectionExtensions.cs
rename to src/Squidex.Read.MongoDb/Utils/MongoCollectionExtensions.cs
index a3ce7e418..a3fee940e 100644
--- a/src/Squidex.Read.MongoDb/Utils/CollectionExtensions.cs
+++ b/src/Squidex.Read.MongoDb/Utils/MongoCollectionExtensions.cs
@@ -16,7 +16,7 @@ using Squidex.Infrastructure.MongoDb;
namespace Squidex.Read.MongoDb.Utils
{
- public static class CollectionExtensions
+ public static class MongoCollectionExtensions
{
public static Task CreateAsync(this IMongoCollection collection, SquidexEvent @event, EnvelopeHeaders headers, Action updater) where T : MongoEntity, new()
{
diff --git a/src/Squidex/Config/Constants.cs b/src/Squidex/Config/Constants.cs
index 58f765584..0c994fb2a 100644
--- a/src/Squidex/Config/Constants.cs
+++ b/src/Squidex/Config/Constants.cs
@@ -10,16 +10,16 @@ namespace Squidex.Config
{
public class Constants
{
- public const string ApiPrefix = "/api";
+ public static readonly string ApiPrefix = "/api";
- public const string ApiScope = "squidex-api";
+ public static readonly string ApiScope = "squidex-api";
- public const string RoleScope = "role";
+ public static readonly string RoleScope = "role";
- public const string ProfileScope = "squidex-profile";
+ public static readonly string ProfileScope = "squidex-profile";
- public const string FrontendClient = "squidex-frontend";
+ public static readonly string FrontendClient = "squidex-frontend";
- public const string IdentityPrefix = "/identity-server";
+ public static readonly string IdentityPrefix = "/identity-server";
}
}
diff --git a/src/Squidex/Pipeline/Swagger/SwaggerHelper.cs b/src/Squidex/Pipeline/Swagger/SwaggerHelper.cs
index 6be947320..7494341d8 100644
--- a/src/Squidex/Pipeline/Swagger/SwaggerHelper.cs
+++ b/src/Squidex/Pipeline/Swagger/SwaggerHelper.cs
@@ -18,7 +18,7 @@ namespace Squidex.Pipeline.Swagger
{
public static class SwaggerHelper
{
- private static ConcurrentDictionary docs = new ConcurrentDictionary();
+ private static readonly ConcurrentDictionary docs = new ConcurrentDictionary();
public static string LoadDocs(string name)
{