Пример #1
0
        public async Task SendPasswordResetTokenAsync(string userName, Dictionary <string, string> additionalClientInfo)
        {
            _logger.Trace("SendPasswordResetToken " + userName);
            ValidateNonEmptyString(userName, nameof(userName));
            const string logErrorFormat = "SendPasswordResetToken failed for {0}: {1}";

            try
            {
                var user = await _userManager.FindByNameAsync(userName);

                var passwordResetToken = await _userManager.GeneratePasswordResetTokenAsync(user);

                // The plugin may choose it's own client error messages (UserException and ClientException will not be suppressed).
                _sendPasswordResetTokenPlugin.Value.SendPasswordResetToken(userName, additionalClientInfo, passwordResetToken);
            }
            catch (Exception ex)
            {
                if (ex is UserException || ex is ClientException)
                {
                    ExceptionsUtility.Rethrow(ex);
                }

                // Don't return an internal error to the client. Log it and return a generic error message:
                _logger.Error(logErrorFormat, userName, ex);
                throw new FrameworkException(ErrorReporting.GetInternalServerErrorMessage(_localizer, ex));
            }
        }
        private void Commit()
        {
            _logger.Trace(() => "Committing (" + _persistenceTransactionId + ").");
            var exceptions = new List <Exception>();

            Try(
                BeforeClose,
                () => BeforeClose = null,
                exceptions);

            Try(
                !exceptions.Any() ? (Action)CommitTransaction : (Action)RollbackTransaction,
                () => _transaction = null,
                exceptions);

            Try(
                CloseConnection,
                () => _connection = null,
                exceptions);

            if (exceptions.Any())
            {
                ExceptionsUtility.Rethrow(exceptions.First());
            }

            AfterClose?.Invoke();
            AfterClose = null;
        }
Пример #3
0
 /// <summary>
 /// Returns plugins that are registered for the given interface, sorted by dependencies (MefPovider.DependsOn).
 /// </summary>
 internal static IEnumerable <PluginInfo> FindPlugins(ContainerBuilder builder, Type pluginInterface)
 {
     lock (_pluginsLock)
     {
         if (_pluginsByExport == null)
         {
             var assemblies = ListAssemblies();
             try
             {
                 _pluginsByExport = LoadPlugins(assemblies);
             }
             catch (Exception ex)
             {
                 string typeLoadReport = CsUtility.ReportTypeLoadException(ex, "Cannot load plugins.", assemblies);
                 if (typeLoadReport != null)
                 {
                     throw new FrameworkException(typeLoadReport, ex);
                 }
                 else
                 {
                     ExceptionsUtility.Rethrow(ex);
                 }
             }
         }
         return(_pluginsByExport.Get(pluginInterface.FullName));
     }
 }
Пример #4
0
        static int Main(string[] args)
        {
            string errorMessage = null;

            try
            {
                Paths.InitializeRhetosServerRootPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\.."));
                Exception createAdminUserException = null;
                try
                {
                    // If CreateAdminUserAndPermissions() fails, this program will still try to execute SetUpAdminAccount() then report the exception later.
                    CreateAdminUserAndPermissions();
                }
                catch (Exception ex)
                {
                    createAdminUserException = ex;
                }

                string password = null;
                for (int i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-pass" && i < args.Length - 1)
                    {
                        password = args[i + 1];
                        break;
                    }
                }

                SetUpAdminAccount(password);

                if (createAdminUserException != null)
                {
                    ExceptionsUtility.Rethrow(createAdminUserException);
                }
            }
            catch (ApplicationException ex)
            {
                errorMessage = "CANCELED: " + ex.Message;
            }
            catch (Exception ex)
            {
                errorMessage = "ERROR: " + ex;
            }

            if (errorMessage != null)
            {
                Console.WriteLine();
                Console.WriteLine(errorMessage);
                if (!args.Any(arg => arg.Equals("/nopause")))
                {
                    Console.WriteLine();
                    Console.Write("Press any key to continue . . .");
                    Console.ReadKey(true);
                }
                return(1);
            }

            return(0);
        }
Пример #5
0
        public List <Token> GetTokensOrException()
        {
            var tokenizerResult = GetTokens();

            if (tokenizerResult.SyntaxError != null)
            {
                ExceptionsUtility.Rethrow(tokenizerResult.SyntaxError);
            }
            return(tokenizerResult.Tokens);
        }
Пример #6
0
        internal static TokenReader TestTokenReader(string dsl, int position = 0)
        {
            var tokenizerResult = new TestTokenizer(dsl).GetTokens();

            if (tokenizerResult.SyntaxError != null)
            {
                ExceptionsUtility.Rethrow(tokenizerResult.SyntaxError);
            }
            return(new TokenReader(tokenizerResult.Tokens, position));
        }
        public void UpdateDatabase()
        {
            _logger.Info("SQL connection: " + SqlUtility.SqlConnectionInfo(SqlUtility.ConnectionString));
            ConnectionTesting.ValidateDbConnection(SqlUtility.ConnectionString, _sqlExecuter);

            _logger.Info("Preparing Rhetos database.");
            PrepareRhetosDatabase();

            // Since IPersistenceTransaction is not registered in the parent container scope,
            // the commands below will not be part of a single shared database transaction.
            // Instead, each command will commit its changes to the database separately.

            _logger.Info("Cleaning old migration data.");
            _databaseCleaner.RemoveRedundantMigrationColumns();
            _databaseCleaner.RefreshDataMigrationRows(); // Resets the data-migration optimization cache, to avoid using stale backup data from old migration tables.

            _logger.Info("Executing data migration scripts.");
            _dataMigrationFromCodeExecuter.ExecuteBeforeDataMigrationScripts();
            var dataMigrationReport = _dataMigrationScriptsExecuter.Execute();

            _dataMigrationFromCodeExecuter.ExecuteAfterDataMigrationScripts();

            _logger.Info("Upgrading database.");
            try
            {
                _databaseGenerator.UpdateDatabaseStructure();
            }
            catch (Exception mainException)
            {
                try
                {
                    if (_options.RepeatDataMigrationsAfterFailedUpdate)
                    {
                        _dataMigrationScriptsExecuter.Undo(dataMigrationReport.CreatedScripts);
                    }
                }
                catch (Exception cleanupException)
                {
                    _logger.Info(cleanupException.ToString());
                }
                ExceptionsUtility.Rethrow(mainException);
            }

            _logger.Info("Deleting redundant migration data.");
            _databaseCleaner.RemoveRedundantMigrationColumns();
            _databaseCleaner.RefreshDataMigrationRows(); // Resets the data-migration optimization cache again.
            // Invalidation the cache *after* upgrade is useful for developers that might develop new data-migration scripts and
            // manually execute them on database, to avoid unintentionally using the old migration data.
            // The migration data might become stale on successful deployment, if any IServerInitializer plugin modifies the main data,
            // for example after-deploy scripts or KeepSynchronized concepts.
        }
Пример #8
0
        public void SendPasswordResetToken(SendPasswordResetTokenParameters parameters)
        {
            if (parameters == null)
            {
                throw new ClientException("It is not allowed to call this authentication service method with no parameters provided.");
            }
            _logger.Trace("SendPasswordResetToken " + parameters.UserName);
            parameters.Validate();

            const string logErrorFormat = "SendPasswordResetToken failed for {0}: {1}";

            try
            {
                string passwordResetToken;
                try
                {
                    var tokenParameters = new GeneratePasswordResetTokenParameters
                    {
                        UserName = parameters.UserName,
                        TokenExpirationInMinutesFromNow = Int32.Parse(ConfigUtility.GetAppSetting("AspNetFormsAuth.SendPasswordResetToken.ExpirationInMinutes") ?? "1440")
                    };
                    passwordResetToken = GeneratePasswordResetTokenInternal(tokenParameters);
                }
                // Providing an error information to the client might be a security issue, because this method allows anonymous access.
                catch (UserException ex)
                {
                    _logger.Trace(logErrorFormat, parameters.UserName, ex);
                    return;
                }
                catch (ClientException ex)
                {
                    _logger.Info(logErrorFormat, parameters.UserName, ex);
                    return;
                }

                // The plugin may choose it's own client error messages (UserException and ClientException will not be suppressed).
                _sendPasswordResetTokenPlugin.Value.SendPasswordResetToken(parameters.UserName, parameters.AdditionalClientInfo, passwordResetToken);
            }
            catch (Exception ex)
            {
                if (ex is UserException || ex is ClientException)
                {
                    ExceptionsUtility.Rethrow(ex);
                }

                // Don't return an internal error to the client. Log it and return a generic error message:
                _logger.Error(logErrorFormat, parameters.UserName, ex);
                throw new FrameworkException(FrameworkException.GetInternalServerErrorMessage(_localizer, ex));
            }
        }
Пример #9
0
        private CodeBuilder BuildCode <TPlugin>(IPluginsContainer <TPlugin> plugins, string tagOpen, string tagClose, IConceptCodeGenerator initialCodeGenerator) where TPlugin : IConceptCodeGenerator
        {
            var stopwatch = Stopwatch.StartNew();

            var codeBuilder = new CodeBuilder(tagOpen, tagClose);

            if (initialCodeGenerator != null)
            {
                initialCodeGenerator.GenerateCode(null, codeBuilder);
            }

            var conceptImplementations = _dslModel.GetTypes()
                                         .ToDictionary(conceptType => conceptType, conceptType => plugins.GetImplementations(conceptType).ToList());

            _performanceLogger.Write(stopwatch, $"Get implementations for {typeof(TPlugin).FullName}.");

            var implementationStopwatches = conceptImplementations.SelectMany(ci => ci.Value)
                                            .Select(plugin => plugin.GetType())
                                            .Distinct()
                                            .ToDictionary(pluginType => pluginType, pluginType => new Stopwatch());

            foreach (var conceptInfo in _dslModel.Concepts)
            {
                foreach (var plugin in conceptImplementations[conceptInfo.GetType()])
                {
                    try
                    {
                        var implementationStopwatch = implementationStopwatches[plugin.GetType()];
                        implementationStopwatch.Start();
                        plugin.GenerateCode(conceptInfo, codeBuilder);
                        implementationStopwatch.Stop();
                    }
                    catch (Exception e)
                    {
                        _logger.Info("Part of the source code that was generated before the exception was thrown is written in the trace log.");
                        _logger.Trace(() => codeBuilder.GenerateCode());
                        ExceptionsUtility.Rethrow(e);
                    }
                }
            }

            foreach (var imp in implementationStopwatches.OrderByDescending(i => i.Value.Elapsed.TotalSeconds).Take(3))
            {
                _performanceLogger.Write(imp.Value, () => $"{typeof(TPlugin).Name} total time for {imp.Key}.");
            }

            _performanceLogger.Write(stopwatch, $"Code generated for {typeof(TPlugin).FullName}.");
            return(codeBuilder);
        }
Пример #10
0
        internal static void Run(string[] args)
        {
            var commands = new List <Action <TransactionScopeContainer> >
            {
                container => CreateAdminUserAndPermissions(container),
                container =>
                {
                    string password = null;
                    for (int i = 0; i < args.Length; i++)
                    {
                        if (args[i] == "-pass" && i < args.Length - 1)
                        {
                            password = args[i + 1];
                            break;
                        }
                    }
                    SetUpAdminAccount(password);
                }
            };

            var processContainer = new ProcessContainer(
                addCustomConfiguration: configurationBuilder => configurationBuilder.AddConfigurationManagerConfiguration());

            // If the first command fails ("CreateAdminUserAndPermissions"), this program will still try to execute "SetUpAdminAccount" then report the exception later.
            var exceptions = new List <Exception>();

            foreach (var command in commands)
            {
                try
                {
                    using (var container = processContainer.CreateTransactionScopeContainer())
                    {
                        command(container);
                        container.CommitChanges();
                    }
                }
                catch (Exception ex)
                {
                    exceptions.Add(ex);
                }
            }

            if (exceptions.Any())
            {
                ExceptionsUtility.Rethrow(exceptions.First());
            }
        }
Пример #11
0
        /// <param name="saveException">SqlException, or an exception that has SqlException as an inner exception (directly or indirectly).</param>
        public static void ThrowInterpretedException(bool checkUserPermissions, Exception saveException, RhetosException interpretedException, ISqlUtility sqlUtility, string tableName)
        {
            if (checkUserPermissions)
            {
                MsSqlUtility.ThrowIfPrimaryKeyErrorOnInsert(interpretedException, tableName);
            }
            if (interpretedException != null)
            {
                ExceptionsUtility.Rethrow(interpretedException);
            }
            var sqlException = sqlUtility.ExtractSqlException(saveException);

            if (sqlException != null)
            {
                ExceptionsUtility.Rethrow(sqlException);
            }
            ExceptionsUtility.Rethrow(saveException);
        }
Пример #12
0
        private static void CreateAdminUserAndPermissions()
        {
            string    oldDirectory      = Directory.GetCurrentDirectory();
            Exception originalException = null;

            try
            {
                Directory.SetCurrentDirectory(Paths.RhetosServerRootPath);
                using (var container = CreateRhetosContainer())
                {
                    try
                    {
                        var repositories = container.Resolve <GenericRepositories>();
                        ConsoleLogger.MinLevel = EventType.Info;
                        new AdminUserInitializer(repositories).Initialize();
                    }
                    catch (Exception ex)
                    {
                        // Some exceptions result with invalid SQL transaction state that results with another exception on disposal of this 'using' block.
                        // The original exception is logged here to make sure that it is not overridden;
                        originalException = ex;

                        container.Resolve <IPersistenceTransaction>().DiscardChanges();
                        ExceptionsUtility.Rethrow(ex);
                    }
                }
            }
            catch (Exception ex)
            {
                if (originalException != null && ex != originalException)
                {
                    Console.WriteLine("Error on cleanup: " + ex.ToString());
                    ExceptionsUtility.Rethrow(originalException);
                }
                else
                {
                    ExceptionsUtility.Rethrow(ex);
                }
            }
            finally
            {
                Directory.SetCurrentDirectory(oldDirectory);
            }
        }
Пример #13
0
 private void FailOnTypeLoadErrors(Assembly assembly, string outputAssemblyPath, IEnumerable <string> referencedAssembliesPaths)
 {
     try
     {
         assembly.GetTypes();
     }
     catch (Exception ex)
     {
         string contextInfo    = $"Error while compiling {Path.GetFileName(outputAssemblyPath)}.";
         string typeLoadReport = CsUtility.ReportTypeLoadException(ex, contextInfo, referencedAssembliesPaths);
         if (typeLoadReport != null)
         {
             throw new FrameworkException(typeLoadReport, ex);
         }
         else
         {
             ExceptionsUtility.Rethrow(ex);
         }
     }
 }
Пример #14
0
        public void UpdateDatabase()
        {
            _logger.Info("SQL connection: " + SqlUtility.SqlConnectionInfo(SqlUtility.ConnectionString));
            ConnectionStringReport.ValidateDbConnection(_sqlExecuter);

            _logger.Info("Preparing Rhetos database.");
            PrepareRhetosDatabase();

            _logger.Info("Cleaning old migration data.");
            _databaseCleaner.RemoveRedundantMigrationColumns();
            _databaseCleaner.RefreshDataMigrationRows();

            _logger.Info("Executing data migration scripts.");
            _dataMigrationFromCodeExecuter.ExecuteBeforeDataMigrationScripts();
            var dataMigrationReport = _dataMigrationScriptsExecuter.Execute();

            _dataMigrationFromCodeExecuter.ExecuteAfterDataMigrationScripts();

            _logger.Info("Upgrading database.");
            try
            {
                _databaseGenerator.UpdateDatabaseStructure();
            }
            catch (Exception ex)
            {
                try
                {
                    _dataMigrationScriptsExecuter.Undo(dataMigrationReport.CreatedScripts);
                }
                catch (Exception undoException)
                {
                    _logger.Info(undoException.ToString());
                }
                ExceptionsUtility.Rethrow(ex);
            }

            _logger.Info("Deleting redundant migration data.");
            _databaseCleaner.RemoveRedundantMigrationColumns();
            _databaseCleaner.RefreshDataMigrationRows();
        }
Пример #15
0
        /// <summary>
        /// Note:
        /// This method does not conform to the standard IoC design pattern.
        /// It uses IoC container directly because it needs to handle a special scope control (separate database connections) and error handling.
        /// </summary>
        public static void ExecuteInitializer(IContainer container, Type initializerType)
        {
            var logger = container.Resolve <ILogProvider>().GetLogger(nameof(ApplicationInitialization));

            Exception originalException = null;

            try
            {
                using (var initializerScope = container.BeginLifetimeScope())
                    try
                    {
                        logger.Info($"Initialization {initializerType.Name}.");
                        var initializers = initializerScope.Resolve <IPluginsContainer <IServerInitializer> >().GetPlugins();
                        IServerInitializer initializer = initializers.Single(i => i.GetType() == initializerType);
                        initializer.Initialize();
                    }
                    catch (Exception ex)
                    {
                        // Some exceptions result with invalid SQL transaction state that results with another exception on disposal of this 'using' block.
                        // The original exception is logged here to make sure that it is not overridden.
                        originalException = ex;
                        initializerScope.Resolve <IPersistenceTransaction>().DiscardChanges();
                        ExceptionsUtility.Rethrow(ex);
                    }
            }
            catch (Exception ex)
            {
                if (originalException != null && ex != originalException)
                {
                    logger.Error($"Error on cleanup: {ex}");
                    ExceptionsUtility.Rethrow(originalException);
                }
                else
                {
                    ExceptionsUtility.Rethrow(ex);
                }
            }
        }
Пример #16
0
 public static void WriteToDatabase <TEntity>(
     IEnumerable <TEntity> insertedNew,
     IEnumerable <TEntity> updatedNew,
     IEnumerable <TEntity> deletedIds,
     IPersistenceStorage persistenceStorage,
     bool checkUserPermissions,
     ISqlUtility sqlUtility,
     out Exception saveException,
     out RhetosException interpretedException)
     where TEntity : class, IEntity
 {
     try
     {
         persistenceStorage.Save(insertedNew, updatedNew, deletedIds);
         saveException        = null;
         interpretedException = null;
     }
     catch (NonexistentRecordException nre)
     {
         saveException        = null;
         interpretedException = null;
         if (checkUserPermissions)
         {
             throw new ClientException(nre.Message);
         }
         else
         {
             ExceptionsUtility.Rethrow(nre);
         }
     }
     catch (SqlException e)
     {
         saveException        = e;
         interpretedException = sqlUtility.InterpretSqlException(saveException);
     }
 }
Пример #17
0
        private MultiDictionary <string, PluginInfo> GetPluginsByExport(IEnumerable <string> pluginAssemblies)
        {
            List <string> assemblyPaths = pluginAssemblies.Select(path => Path.GetFullPath(path)).Distinct().ToList();

            foreach (var assembly in assemblyPaths)
            {
                if (!File.Exists(assembly))
                {
                    throw new FrameworkException($"{nameof(PluginScanner)}: The given assembly file path does not exist: '{assembly}'.");
                }
                else
                {
                    _logger.Trace(() => $"Searching for plugins in '{assembly}'");
                }
            }

            MultiDictionary <string, PluginInfo> plugins = null;

            try
            {
                plugins = LoadPlugins(assemblyPaths);
            }
            catch (Exception ex)
            {
                string typeLoadReport = CsUtility.ReportTypeLoadException(ex, "Cannot load plugins.", assemblyPaths);
                if (typeLoadReport != null)
                {
                    throw new FrameworkException(typeLoadReport, ex);
                }
                else
                {
                    ExceptionsUtility.Rethrow(ex);
                }
            }
            return(plugins);
        }
Пример #18
0
        public void ExecuteGenerators(bool deployDatabaseOnly)
        {
            _deployPackagesLogger.Trace("SQL connection: " + SqlUtility.SqlConnectionInfo(SqlUtility.ConnectionString));
            ValidateDbConnection();

            _deployPackagesLogger.Trace("Preparing Rhetos database.");
            PrepareRhetosDatabase();

            _deployPackagesLogger.Trace("Parsing DSL scripts.");
            int dslModelConceptsCount = _dslModel.Concepts.Count();

            _deployPackagesLogger.Trace("Application model has " + dslModelConceptsCount + " statements.");

            if (deployDatabaseOnly)
            {
                _deployPackagesLogger.Info("Skipped code generators (DeployDatabaseOnly).");
            }
            else
            {
                _deployPackagesLogger.Trace("Compiling DOM assembly.");
                int generatedTypesCount = _domGenerator.GetTypes().Count();
                if (generatedTypesCount == 0)
                {
                    _deployPackagesLogger.Info("Warning: Empty assembly is generated.");
                }
                else
                {
                    _deployPackagesLogger.Trace("Generated " + generatedTypesCount + " types.");
                }

                var generators = GetSortedGenerators();
                foreach (var generator in generators)
                {
                    _deployPackagesLogger.Trace("Executing " + generator.GetType().Name + ".");
                    generator.Generate();
                }
                if (!generators.Any())
                {
                    _deployPackagesLogger.Trace("No additional generators.");
                }
            }

            _deployPackagesLogger.Trace("Cleaning old migration data.");
            _databaseCleaner.RemoveRedundantMigrationColumns();
            _databaseCleaner.RefreshDataMigrationRows();

            _dataMigrationFromCodeExecuter.ExecuteBeforeDataMigrationScripts();

            _deployPackagesLogger.Trace("Executing data migration scripts.");
            var dataMigrationReport = _dataMigration.Execute();

            _dataMigrationFromCodeExecuter.ExecuteAfterDataMigrationScripts();

            _deployPackagesLogger.Trace("Upgrading database.");
            try
            {
                _databaseGenerator.UpdateDatabaseStructure();
            }
            catch (Exception ex)
            {
                try
                {
                    _dataMigration.Undo(dataMigrationReport.CreatedTags);
                }
                catch (Exception undoException)
                {
                    _deployPackagesLogger.Error(undoException.ToString());
                }
                ExceptionsUtility.Rethrow(ex);
            }

            _deployPackagesLogger.Trace("Deleting redundant migration data.");
            _databaseCleaner.RemoveRedundantMigrationColumns();
            _databaseCleaner.RefreshDataMigrationRows();

            _deployPackagesLogger.Trace("Uploading DSL scripts.");
            UploadDslScriptsToServer();
        }
Пример #19
0
        private List <ConceptSyntaxNode> ExtractConcepts(MultiDictionary <string, IConceptParser> conceptParsers)
        {
            var stopwatch = Stopwatch.StartNew();

            var tokenizerResult = _tokenizer.GetTokens();

            if (tokenizerResult.SyntaxError != null)
            {
                ExceptionsUtility.Rethrow(tokenizerResult.SyntaxError);
            }
            var tokenReader = new TokenReader(tokenizerResult.Tokens, 0);

            var newConcepts = new List <ConceptSyntaxNode>();
            var context     = new Stack <ConceptSyntaxNode>();
            var warnings    = new List <string>();

            tokenReader.SkipEndOfFile();
            while (!tokenReader.EndOfInput)
            {
                var parsed = ParseNextConcept(tokenReader, context, conceptParsers);
                newConcepts.Add(parsed.ConceptInfo);

                if (parsed.Warnings != null)
                {
                    warnings.AddRange(parsed.Warnings);
                }

                UpdateContextForNextConcept(tokenReader, context, parsed.ConceptInfo);
                OnKeyword?.Invoke(tokenReader, null);

                if (context.Count == 0)
                {
                    tokenReader.SkipEndOfFile();
                }
            }

            _performanceLogger.Write(stopwatch, "ExtractConcepts (" + newConcepts.Count + " concepts).");

            if (context.Count > 0)
            {
                var(dslScript, position) = tokenReader.GetPositionInScript();
                throw new DslSyntaxException($"Expected \"}}\" to close concept \"{context.Peek()}\".",
                                             "RH0002", dslScript, position, 0, ReportPreviousConcept(context.Peek()));
            }

            foreach (string warning in warnings)
            {
                if (_syntax.Value.ExcessDotInKey == ExcessDotInKey.Ignore)
                {
                    _logger.Trace(warning);
                }
                else
                {
                    _logger.Warning(warning);
                }
            }
            if (_syntax.Value.ExcessDotInKey == ExcessDotInKey.Error && warnings.Any())
            {
                throw new DslSyntaxException(warnings.First());
            }

            return(newConcepts);
        }