Beispiel #1
0
        public static void PostStart()
        {
            BasicMembershipAuthHttpModule.Realm = "SSBT.web";

            Database.SetInitializer(new DropCreateDatabaseIfModelChanges <SSBTDbContext>());

            using (var ddb = new SSBTDbContext())
            {
                ddb.Database.Initialize(false);
            }

            MembershipUser defaultUser = null;

            if (Membership.GetAllUsers().Count == 0)
            {
                defaultUser = Membership.CreateUser("admin", "password");
            }

            if (!Roles.RoleExists("Admin"))
            {
                Roles.CreateRole("Admin");

                if (defaultUser != null)
                {
                    Roles.AddUserToRole(defaultUser.UserName, "Admin");
                }
            }

            if (!Roles.RoleExists("Operator"))
            {
                Roles.CreateRole("Operator");
            }
        }
Beispiel #2
0
        protected override void Initialize(RequestContext r)
        {
            var controllerName = r.RouteData.GetRequiredString("controller");
            var actionName     = r.RouteData.GetRequiredString("action");

            ViewBag.ControllerName = controllerName;
            Logger    = LogManager.GetLogger(string.Format("{0}_{1}", controllerName, actionName));
            DbContext = new SSBTDbContext();

            base.Initialize(r);
        }
        /// <summary>
        /// Fetches the list of databases available on SQLServer, with additional information.
        /// </summary>
        /// <param name="user"><see cref="IPrincipal"/> used to filter final results with authorized databases</param>
        /// <returns>A list of <see cref="DatabaseInfo"/></returns>
        public static async Task <List <DatabaseInfo> > GetDatabasesInfo([NotNull] IPrincipal user)
        {
            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            using (var co = new SqlConnection(GetBackupsConnectionString()))
            {
                await co.OpenAsync();

                var p = await Task.Run(() => co.Query <DatabaseInfo>(DatabaseInfo.Query).OrderBy(_ => _.Id).ToList());

                foreach (var info in p.Where(_ => _.IsOnline))
                {
                    try
                    {
                        co.ChangeDatabase(info.Name);
                    }
                    catch (SqlException) // Security problem, user is usually not authorized to access the database
                    {
                        info.IsOnline = false;
                        continue;
                    }

                    var size = await Task.Run(() => co.Query <DatabaseSizeInfo>(DatabaseSizeInfo.Query).First());

                    if (size != null && !string.IsNullOrEmpty(size.DatabaseSize))
                    {
                        info.Size = size.DatabaseSize;
                    }
                }

                using (var ddb = new SSBTDbContext())
                {
                    p = p.Where(_ => IsDatabaseAuthorized(ddb, user, _.Name)).ToList();
                }

                return(p);
            }
        }
        /// <summary>
        /// Backup purging deletion logic. Each backup is created with an <see cref="BackupHistory.Expires"/> DateTime, all backups
        /// that reached the expiration date will be deleted, their <see cref="SSBTDbContext.History"/> entry deleted too.
        /// </summary>
        /// <param name="ddb">An instance of <see cref="SSBTDbContext"/> </param>
        /// <param name="from">Reference date to compare <see cref="BackupHistory.Expires"/> with</param>
        /// <param name="logger">Optional instance of a <see cref="Logger"/></param>
        /// <returns>true if nothing was expired, or if everything went good during purge. false if <see cref="DbContext.SaveChanges"/> encountered an exception.</returns>
        public static bool PurgeOldBackups([NotNull] SSBTDbContext ddb, DateTime from, [CanBeNull] Logger logger)
        {
            if (ddb == null)
            {
                throw new ArgumentNullException("ddb");
            }

            var oldBackups = ddb.History
                             .Where(_ => from > _.Expires)
                             .ToList();

            var didChange = false;

            foreach (var b in oldBackups)
            {
                if (DeleteBackup(ddb, b, logger))
                {
                    didChange = true;
                }
            }

            if (!didChange)
            {
                return(true);
            }

            try
            {
                ddb.SaveChanges();
            }
            catch (Exception ex)
            {
                if (logger != null)
                {
                    logger.ErrorException("While saving database changes", ex);
                }
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Backup deletion logic, deletes a database backup represented as a <see cref="BackupHistory"/>.
        /// Deletes the recorded archive file then marks the <see cref="BackupHistory"/> entity for deletion in <see cref="ddb"/>
        /// </summary>
        /// <param name="ddb">An instance of <see cref="SSBTDbContext"/></param>
        /// <param name="b">The <see cref="BackupHistory"/> instance to delete</param>
        /// <param name="logger">Optional instance of a <see cref="Logger"/></param>
        /// <returns>true if everything went good, false otherwise.</returns>
        /// <remarks>If the database backup archive fails to be deleted for any reason, a log will be written but the <see cref="b"/> won't be marked for deletion.</remarks>
        public static bool DeleteBackup([NotNull] SSBTDbContext ddb, BackupHistory b, [CanBeNull] Logger logger)
        {
            if (ddb == null)
            {
                throw new ArgumentNullException("ddb");
            }

            try
            {
                File.Delete(b.Path);
            }
            catch (Exception ex)
            {
                if (logger != null)
                {
                    logger.ErrorException(String.Format("During backup file deletion '{0}'", b.Path), ex);
                }
                return(false);
            }

            ddb.History.Remove(b);
            return(true);
        }
        /// <summary>
        /// Determines if the given <see cref="user"/> is allowed to make any action on the database named <see cref="databaseName"/>
        /// If the <see cref="user"/> is an admin or an operator, returns true. In any other case the table UserDatabase table is checked
        /// </summary>
        /// <param name="ddb">A valid <see cref="SSBTDbContext"/> db context</param>
        /// <param name="user">The <see cref="IPrincipal"/> to test</param>
        /// <param name="databaseName">The name of the database to tes</param>
        /// <returns>true or false</returns>
        public static bool IsDatabaseAuthorized([NotNull] SSBTDbContext ddb, [CanBeNull] IPrincipal user, [CanBeNull] string databaseName)
        {
            if (ddb == null)
            {
                throw new ArgumentNullException("ddb");
            }

            if (user == null)
            {
                return(false);
            }

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                return(false);
            }

            if (user.IsInRole("Admin") || user.IsInRole("Operator"))
            {
                return(true);
            }

            var uname = user.Identity.Name;

            if (string.IsNullOrWhiteSpace(uname))
            {
                return(false);
            }

            var isAuthorized = ddb.UserDatabases.Any(_ =>
                                                     _.Username.Trim().ToLowerInvariant() == uname.Trim().ToLowerInvariant() &&
                                                     _.DatabaseName.Trim().ToLowerInvariant() == databaseName.Trim().ToLowerInvariant()
                                                     );

            return(isAuthorized);
        }
        /// <summary>
        /// Backup implementation logic, asks SQLServer to make a backup, of <see cref="dbName"/>, creates a Zip archive on success, tries to delete the original backup file.
        /// </summary>
        /// <param name="coString">Connection string to use to instruct SQLServer to make the backup</param>
        /// <param name="dbName">Name of the database to backup</param>
        /// <param name="principal"></param>
        /// <param name="logger">Optional instance of a <see cref="Logger"/></param>
        /// <returns>An instance of <see cref="BackupHistory"/> on success, null otherwise</returns>
        /// <remarks>If deletion of the original backup file fails for any reason, only a log entry will be done, the backup won't be considered as failed.
        /// This methods needs to be run in a valid <see cref="HttpContext"/>.
        /// </remarks>
        public static async Task <BackupHistory> BackupDatabase([NotNull] string coString, [NotNull] string dbName, [CanBeNull] Logger logger)
        {
            if (string.IsNullOrWhiteSpace(coString))
            {
                throw new ArgumentNullException("coString");
            }

            if (string.IsNullOrWhiteSpace(dbName))
            {
                throw new ArgumentNullException("dbName");
            }

            var httpContext = HttpContext.Current;

            if (httpContext == null)
            {
                throw new Exception("HttpContext.Current returned null");
            }

            var server = httpContext.Server;
            var user   = httpContext.User;

            using (var bak = new SqlServerBackupProvider(coString))
            {
                await bak.OpenAsync();

                var ts = DateTime.Now;

                var backupsPath = server.MapPath("~/Backups");

                var fNameBase = Utils.GenerateBackupBaseName(dbName, ts);

                var fullBackupPath = Path.Combine(backupsPath, string.Format("{0}.bak", fNameBase));

                try
                {
                    await bak.BackupDatabaseAsync(dbName, fullBackupPath, ts);
                }
                catch (Exception ex)
                {
                    if (logger != null)
                    {
                        logger.ErrorException("During database backup", ex);
                    }
                    return(null);
                }

                var fullZipPath = Path.Combine(backupsPath, string.Format("{0}.zip", fNameBase));

                try
                {
                    using (var z = new ZipFile(fullZipPath))
                    {
                        z.AddFile(fullBackupPath, string.Empty);

                        await Task.Run(() => z.Save());
                    }
                }
                catch (Exception ex)
                {
                    if (logger != null)
                    {
                        logger.ErrorException("During zip file creation", ex);
                    }
                    return(null);
                }

                try
                {
                    File.Delete(fullBackupPath);
                }
                catch (Exception ex)
                {
                    if (logger != null)
                    {
                        logger.ErrorException("During original file deletion", ex);
                    }
                }

                var fInfo = new FileInfo(fullZipPath);

                var h = new BackupHistory
                {
                    Path     = fullZipPath,
                    Database = dbName,
                    Url      = string.Format("~/{0}", fullZipPath.Replace(server.MapPath("~/"), string.Empty).Replace('\\', '/')),
                    Expires  = DateTime.Now.AddDays(1),
                    Username = user.Identity.Name,
                    Size     = fInfo.Length,
                };

                using (var ddb = new SSBTDbContext())
                {
                    ddb.History.Add(h);
                    ddb.SaveChanges();
                }

                return(h);
            }
        }