// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschränkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using NodaTime; using Squidex.Areas.Api.Controllers.Assets; using Squidex.Areas.Api.Controllers.Backups; using Squidex.Areas.Api.Controllers.Ping; using Squidex.Areas.Api.Controllers.Plans; using Squidex.Areas.Api.Controllers.Rules; using Squidex.Areas.Api.Controllers.Schemas; using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Apps.Services; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Security; using Squidex.Shared; using Squidex.Web; using AllPermissions = Squidex.Shared.Permissions; namespace Squidex.Areas.Api.Controllers.Apps.Models { public sealed class AppDto : Resource, IGenerateETag { /// /// The name of the app. /// [Required] [RegularExpression("^[a-z0-9]+(\\-[a-z0-9]+)*$")] public string Name { get; set; } /// /// The version of the app. /// public long Version { get; set; } /// /// The id of the app. /// public Guid Id { get; set; } /// /// The timestamp when the app has been created. /// public Instant Created { get; set; } /// /// The timestamp when the app has been modified last. /// public Instant LastModified { get; set; } /// /// The permission level of the user. /// public IEnumerable Permissions { get; set; } /// /// Indicates if the user can access the api. /// public bool CanAccessApi { get; set; } /// /// Indicates if the user can access at least one content. /// public bool CanAccessContent { get; set; } /// /// Gets the current plan name. /// public string PlanName { get; set; } /// /// Gets the next plan name. /// public string PlanUpgrade { get; set; } public static AppDto FromApp(IAppEntity app, string userId, PermissionSet userPermissions, IAppPlansProvider plans, ApiController controller) { var permissions = GetPermissions(app, userId, userPermissions); var result = SimpleMapper.Map(app, new AppDto()); result.Permissions = permissions.ToIds(); result.PlanName = plans.GetPlanForApp(app)?.Name; result.CanAccessApi = controller.HasPermission(AllPermissions.AppApi, app.Name, "*", permissions); result.CanAccessContent = controller.HasPermission(AllPermissions.AppContentsRead, app.Name, "*", permissions); if (controller.HasPermission(AllPermissions.AppPlansChange, app.Name)) { result.PlanUpgrade = plans.GetPlanUpgradeForApp(app)?.Name; } return result.CreateLinks(controller, permissions); } private static PermissionSet GetPermissions(IAppEntity app, string userId, PermissionSet userPermissions) { var permissions = new List(); if (app.Contributors.TryGetValue(userId, out var roleName) && app.Roles.TryGetValue(roleName, out var role)) { permissions.AddRange(role.Permissions); } if (userPermissions != null) { permissions.AddRange(userPermissions.ToAppPermissions(app.Name)); } return new PermissionSet(permissions); } private AppDto CreateLinks(ApiController controller, PermissionSet permissions) { var values = new { app = Name }; AddGetLink("ping", controller.Url(x => nameof(x.GetAppPing), values)); if (controller.HasPermission(AllPermissions.AppDelete, Name, permissions: permissions)) { AddDeleteLink("delete", controller.Url(x => nameof(x.DeleteApp), values)); } if (controller.HasPermission(AllPermissions.AppAssetsRead, Name, permissions: permissions)) { AddGetLink("assets", controller.Url(x => nameof(x.GetAssets), values)); } if (controller.HasPermission(AllPermissions.AppBackupsRead, Name, permissions: permissions)) { AddGetLink("backups", controller.Url(x => nameof(x.GetBackups), values)); } if (controller.HasPermission(AllPermissions.AppClientsRead, Name, permissions: permissions)) { AddGetLink("clients", controller.Url(x => nameof(x.GetClients), values)); } if (controller.HasPermission(AllPermissions.AppContributorsRead, Name, permissions: permissions)) { AddGetLink("contributors", controller.Url(x => nameof(x.GetContributors), values)); } if (controller.HasPermission(AllPermissions.AppCommon, Name, permissions: permissions)) { AddGetLink("languages", controller.Url(x => nameof(x.GetLanguages), values)); } if (controller.HasPermission(AllPermissions.AppCommon, Name, permissions: permissions)) { AddGetLink("patterns", controller.Url(x => nameof(x.GetPatterns), values)); } if (controller.HasPermission(AllPermissions.AppPlansRead, Name, permissions: permissions)) { AddGetLink("plans", controller.Url(x => nameof(x.GetPlans), values)); } if (controller.HasPermission(AllPermissions.AppRolesRead, Name, permissions: permissions)) { AddGetLink("roles", controller.Url(x => nameof(x.GetRoles), values)); } if (controller.HasPermission(AllPermissions.AppRulesRead, Name, permissions: permissions)) { AddGetLink("rules", controller.Url(x => nameof(x.GetRules), values)); } if (controller.HasPermission(AllPermissions.AppCommon, Name, permissions: permissions)) { AddGetLink("schemas", controller.Url(x => nameof(x.GetSchemas), values)); } if (controller.HasPermission(AllPermissions.AppSchemasCreate, Name, permissions: permissions)) { AddPostLink("schemas/create", controller.Url(x => nameof(x.PostSchema), values)); } if (controller.HasPermission(AllPermissions.AppAssetsCreate, Name, permissions: permissions)) { AddPostLink("assets/create", controller.Url(x => nameof(x.PostSchema), values)); } return this; } } }