Browse Source

Readme and License

pull/1/head
Sebastian 9 years ago
parent
commit
b54b918b5f
  1. 21
      LICENSE.txt
  2. 32
      README.md
  3. 1
      Squidex.sln.DotSettings
  4. 6
      src/Squidex.Core/Identity/SquidexClaimTypes.cs
  5. 8
      src/Squidex.Core/Identity/SquidexRoles.cs
  6. 8
      src/Squidex.Core/Schemas/Json/JsonFieldModel.cs
  7. 8
      src/Squidex.Core/Schemas/Json/JsonSchemaModel.cs
  8. 2
      src/Squidex.Core/Schemas/Json/SchemaJsonSerializer.cs
  9. 43
      src/Squidex.Core/Schemas/Schema.cs
  10. 4
      src/Squidex.Infrastructure.Redis/RedisInfrastructureErrors.cs
  11. 4
      src/Squidex.Infrastructure.Redis/RedisSubscription.cs
  12. 12
      src/Squidex.Infrastructure/CQRS/CommonHeaders.cs
  13. 12
      src/Squidex.Infrastructure/Security/OpenIdClaims.cs
  14. 2
      src/Squidex.Read.MongoDb/Utils/MongoCollectionExtensions.cs
  15. 12
      src/Squidex/Config/Constants.cs
  16. 2
      src/Squidex/Pipeline/Swagger/SwaggerHelper.cs

21
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.

32
README.md

@ -1 +1,31 @@
# Squidex
![Squidex Logo](media/logo-wide.png "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.
[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=flat-square)](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.

1
Squidex.sln.DotSettings

@ -27,6 +27,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertPropertyToExpressionBody/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToAutoProperty/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToAutoPropertyWhenPossible/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToConstant_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Html_002ETagNotResolved/@EntryIndexedValue">DO_NOT_SHOW</s:String>

6
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:";
}
}

8
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";
}
}

8
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; }
}
}

8
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<long, JsonFieldModel> Fields;
public Dictionary<long, JsonFieldModel> Fields { get; set; }
}
}

2
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(

43
src/Squidex.Core/Schemas/Schema.cs

@ -266,6 +266,31 @@ namespace Squidex.Core.Schemas
Guard.NotNull(errors, nameof(errors));
Guard.NotEmpty(languages, nameof(languages));
ValidateUnknownFields(data, errors);
foreach (var field in fieldsByName.Values)
{
var fieldErrors = new List<string>();
var fieldData = data.GetOrCreate(field.Name, k => new ContentFieldData());
if (field.RawProperties.IsLocalizable)
{
await ValidateLocalizableFieldAsync(languages, fieldData, fieldErrors, field);
}
else
{
await ValidateNonLocalizableField(fieldData, fieldErrors, field);
}
foreach (var error in fieldErrors)
{
errors.Add(new ValidationError(error, field.Name));
}
}
}
private void ValidateUnknownFields(ContentData data, IList<ValidationError> errors)
{
foreach (var fieldData in data)
{
if (!fieldsByName.ContainsKey(fieldData.Key))
@ -273,13 +298,9 @@ namespace Squidex.Core.Schemas
errors.Add(new ValidationError($"{fieldData.Key} is not a known field", fieldData.Key));
}
}
}
foreach (var field in fieldsByName.Values)
{
var fieldErrors = new List<string>();
var fieldData = data.GetOrCreate(field.Name, k => new ContentFieldData());
if (field.RawProperties.IsLocalizable)
private static async Task ValidateLocalizableFieldAsync(HashSet<Language> languages, ContentFieldData fieldData, List<string> fieldErrors, Field field)
{
foreach (var valueLanguage in fieldData.Keys)
{
@ -300,7 +321,8 @@ namespace Squidex.Core.Schemas
await field.ValidateAsync(value, fieldErrors, language);
}
}
else
private static async Task ValidateNonLocalizableField(ContentFieldData fieldData, List<string> fieldErrors, Field field)
{
if (fieldData.Keys.Any(x => x != Language.Invariant.Iso2Code))
{
@ -312,13 +334,6 @@ namespace Squidex.Core.Schemas
await field.ValidateAsync(value, fieldErrors);
}
foreach (var error in fieldErrors)
{
errors.Add(new ValidationError(error, field.Name));
}
}
}
public void Enrich(ContentData data, HashSet<Language> languages)
{
Guard.NotNull(data, nameof(data));

4
src/Squidex.Infrastructure.Redis/InfrastructureErrors.cs → 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");

4
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.");
}
}

12
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";
}
}

12
src/Squidex.Infrastructure/Security/OpenIdClaims.cs

@ -13,31 +13,31 @@ namespace Squidex.Infrastructure.Security
/// <summary>
/// Unique Identifier for the End-User at the Issuer.
/// </summary>
public const string Subject = "sub";
public static readonly string Subject = "sub";
/// <summary>
/// The client id claim.
/// </summary>
public const string ClientId = "client_id";
public static readonly string ClientId = "client_id";
/// <summary>
/// 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.
/// </summary>
public const string Name = "name";
public static readonly string Name = "name";
/// <summary>
/// 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.
/// </summary>
public const string NickName = "nickname";
public static readonly string NickName = "nickname";
/// <summary>
/// Shorthand name by which the End-User wishes to be referred to at the
/// </summary>
public const string PreferredUserName = "preferred_username";
public static readonly string PreferredUserName = "preferred_username";
/// <summary>
/// End-User's preferred e-mail address.
/// </summary>
public const string Email = "email";
public static readonly string Email = "email";
}
}

2
src/Squidex.Read.MongoDb/Utils/CollectionExtensions.cs → 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<T>(this IMongoCollection<T> collection, SquidexEvent @event, EnvelopeHeaders headers, Action<T> updater) where T : MongoEntity, new()
{

12
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";
}
}

2
src/Squidex/Pipeline/Swagger/SwaggerHelper.cs

@ -18,7 +18,7 @@ namespace Squidex.Pipeline.Swagger
{
public static class SwaggerHelper
{
private static ConcurrentDictionary<string, string> docs = new ConcurrentDictionary<string, string>();
private static readonly ConcurrentDictionary<string, string> docs = new ConcurrentDictionary<string, string>();
public static string LoadDocs(string name)
{

Loading…
Cancel
Save