Skip to content

Fix such this is only done if security package is installed. #22

@github-actions

Description

@github-actions

//TODO : Fix such this is only done if security package is installed.

using EAVFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json.Linq;
using Semver;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace EAVFW.Extensions.Manifest.SDK.Migrations
{
    public class MigrationResult
    {
        public ManifestDefinition Model { get; set; }
        public string SQL { get; set; }
        public string Permissions { get; set; }

    }
    public class SQLMigrationGenerator
    {
        private readonly IParameterGenerator _parameterGenerator;
        private readonly IManifestPermissionGenerator manifestPermissionGenerator;

        public SQLMigrationGenerator(IParameterGenerator parameterGenerator,IManifestPermissionGenerator manifestPermissionGenerator)
        {
            _parameterGenerator = parameterGenerator;
            this.manifestPermissionGenerator = manifestPermissionGenerator;
        }

        public static string GetCombinedFileHash(IEnumerable<string> filenames)
        {
            using (var sha256 = SHA256.Create())
            {
                foreach (var filename in filenames)
                {
                    if (File.Exists(filename))
                    {
                        using (var stream = File.OpenRead(filename))
                        {
                            var buffer = new byte[8192];
                            int bytesRead;
                            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                sha256.TransformBlock(buffer, 0, bytesRead, buffer, 0);
                            }
                        }
                    }
                    else
                    {
                        throw new FileNotFoundException($"File not found: {filename}");
                    }
                }

                // Finalize the hash computation
                sha256.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
                return BitConverter.ToString(sha256.Hash).Replace("-", "").ToLowerInvariant();
            }
        }

        public async Task<MigrationResult> GenerateSQL(string projectPath, bool shouldGeneratePermissions, string systemEntity,
            Action<SqlServerDbContextOptionsBuilder> extend=null)
        {
            var schema = _parameterGenerator.GetParameter("DBSchema",false);// "$(DBSchema)";
            var definition = JsonSerializer.Deserialize<ManifestDefinition>(File.ReadAllText(Path.Combine(projectPath, "obj", "manifest.g.json")));
            var model = JToken.Parse(File.ReadAllText(Path.Combine(projectPath, "obj", "manifest.g.json")));
            var models = Directory.Exists(Path.Combine(projectPath, "manifests")) ? Directory.EnumerateFiles(Path.Combine(projectPath, "manifests"))
                .Select(file => JToken.Parse(File.ReadAllText(file)))
                .OrderByDescending(k => Semver.SemVersion.Parse(k.SelectToken("$.version").ToString(), Semver.SemVersionStyles.Strict), SemVersion.SortOrderComparer)
                .ToArray() : Array.Empty<JToken>();

            //var inputHash = GetCombinedFileHash((Directory.Exists(Path.Combine(projectPath, "manifests")) ? Directory.EnumerateFiles(Path.Combine(projectPath, "manifests"))
            //    .Select(file => file)
            //    .OrderByDescending(k => k)
            //    .ToArray() : Array.Empty<string>()).Concat(new[] { Path.Combine(projectPath, "obj", "manifest.g.json") }));

            var optionsBuilder = new DbContextOptionsBuilder<DynamicContext>();
            //  optionsBuilder.UseInMemoryDatabase("test");
           optionsBuilder.UseSqlServer("dummy",   x =>
           {
               x.MigrationsHistoryTable("__MigrationsHistory", schema);
               extend?.Invoke(x);
           }
           );
         
            optionsBuilder.EnableSensitiveDataLogging();

            optionsBuilder.EnableDetailedErrors();
            optionsBuilder.ReplaceService<IMigrationsAssembly, DbSchemaAwareMigrationAssembly>();

            var ctx = new DynamicContext(optionsBuilder.Options, Microsoft.Extensions.Options.Options.Create(
                 new EAVFramework.DynamicContextOptions
                 {
                     Manifests = new[] { model }.Concat(models).ToArray(),
                     Schema = schema,
                     EnableDynamicMigrations = true,
                     Namespace = "EAVFW.Extensions.Manifest",
                     // DTOAssembly = typeof(ApplicationExtensions).Assembly,
                     // DTOBaseClasses = new[] { typeof(BaseOwnerEntity<Model.Identity>), typeof(BaseIdEntity<Model.Identity>), typeof(KeyValueEntity<Model.Identity>) }
                 }),
                 new MigrationManager(NullLogger<MigrationManager>.Instance, Microsoft.Extensions.Options.Options.Create(new MigrationManagerOptions()
                 {
                     SkipValidateSchemaNameForRemoteTypes = true,
                     Schema = schema,
                     Namespace = "EAVFW.Extensions.Manifest",
                 }), new DynamicCodeServiceFactory())
                 , NullLogger<DynamicContext>.Instance);


            
                var migrator = ctx.Database.GetInfrastructure().GetRequiredService<IMigrator>();

                var sql = migrator.GenerateScript(options: MigrationsSqlGenerationOptions.Idempotent| MigrationsSqlGenerationOptions.NoTransactions | MigrationsSqlGenerationOptions.Default);

                var result = new MigrationResult { Model = definition, SQL = sql }; ;
           

            if (shouldGeneratePermissions)
                result.Permissions = await InitializeSystemAdministrator(result.Model, systemEntity);

            return result;
            
        }
        public async Task<string> InitializeSystemAdministrator(ManifestDefinition model, string systemUserEntity)
        {
            //TODO : Fix such this is only done if security package is installed.

            var sb = await manifestPermissionGenerator.CreateInitializationScript(model, systemUserEntity);

            return sb;

        }


    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions