From 35e94c2e94c32ff1731acb8d02b20e4accc3ca4a Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 25 Mar 2017 19:39:42 -0400 Subject: [PATCH] Database backup creation :smiley: --- Project-Unite/Controllers/AdminController.cs | 59 +++++++++++++++++ Project-Unite/Models/IdentityModels.cs | 10 +++ Project-Unite/Models/ManageViewModels.cs | 6 ++ Project-Unite/Project-Unite.csproj | 3 + Project-Unite/Views/Admin/Backups.cshtml | 66 ++++++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 Project-Unite/Views/Admin/Backups.cshtml diff --git a/Project-Unite/Controllers/AdminController.cs b/Project-Unite/Controllers/AdminController.cs index a865ba7..a487dd3 100644 --- a/Project-Unite/Controllers/AdminController.cs +++ b/Project-Unite/Controllers/AdminController.cs @@ -110,6 +110,65 @@ public ActionResult CreateUser(CreateUserModel model) return RedirectToAction("Users"); } + public ActionResult BackupDatabase() + { + var db = new ApplicationDbContext(); + string backupDir = "~/Backups/Database"; + string backupServerDir = Server.MapPath(backupDir); + if (!System.IO.Directory.Exists(backupServerDir)) + System.IO.Directory.CreateDirectory(backupServerDir); + + string backupUrl = backupDir.Remove(0, 1) + "/ShiftOS-" + DateTime.Now.ToString() + ".zip"; + string backupname = backupServerDir + "\\ShiftOS-" + DateTime.Now.ToString() + ".zip"; + + System.IO.Compression.ZipFile.CreateFromDirectory(Server.MapPath("~/Uploads", backupname)); + + var backupData = new DatabaseBackup(); + backupData.Id = Guid.NewGuid().ToString(); + backupData.UserId = User.Identity.GetUserId(); + backupData.DownloadUrl = backupUrl; + backupData.Timestamp = DateTime.Now; + db.AssetBackups.Add(backupData); + db.SaveChanges(); + return RedirectToAction("Backups"); + } + + public ActionResult BackupAssets() + { + var db = new ApplicationDbContext(); + string backupDir = "~/Backups/Assets"; + string backupServerDir = Server.MapPath(backupDir); + if (!System.IO.Directory.Exists(backupServerDir)) + System.IO.Directory.CreateDirectory(backupServerDir); + + string backupUrl = backupDir.Remove(0, 1) + "/ShiftOS-" + DateTime.Now.ToString() + ".sql"; + string backupname = backupServerDir + "\\ShiftOS-" + DateTime.Now.ToString() + ".sql"; + const string sqlCommand = @"BACKUP DATABASE [{0}] TO DISK = N'{1}' WITH NOFORMAT, NOINIT, NAME = N'ShiftOS Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10"; + int path = db.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, string.Format(sqlCommand, db.Database.Connection.Database, backupname)); + var backupData = new DatabaseBackup(); + backupData.Id = Guid.NewGuid().ToString(); + backupData.UserId = User.Identity.GetUserId(); + backupData.DownloadUrl = backupUrl; + backupData.Timestamp = DateTime.Now; + db.Backups.Add(backupData); + db.SaveChanges(); + return RedirectToAction("Backups"); + } + + + + + public ActionResult Backups() + { + ViewBag.Admin = true; + var backups = new BackupViewModel(); + var db = new ApplicationDbContext(); + backups.Databases = db.Backups.OrderByDescending(x => x.Timestamp); + backups.AssetFolders = db.AssetBackups.OrderByDescending(x => x.Timestamp); + + return View(backups); + } + public void DeleteTopic(ForumTopic topic) { foreach(var post in topic.Posts.ToArray()) diff --git a/Project-Unite/Models/IdentityModels.cs b/Project-Unite/Models/IdentityModels.cs index 187bad3..ced6fc3 100644 --- a/Project-Unite/Models/IdentityModels.cs +++ b/Project-Unite/Models/IdentityModels.cs @@ -204,6 +204,8 @@ public static ApplicationDbContext Create() return new ApplicationDbContext(); } + public DbSet Backups { get; set; } + public DbSet AssetBackups { get; set; } public DbSet UserAvatars { get; set; } public DbSet Skins { get; set; } public DbSet Configs { get; set; } @@ -278,4 +280,12 @@ public class Avatar public string AvatarUrl { get; set; } public DateTime UploadedAt { get; set; } } + + public class DatabaseBackup + { + public string Id { get; set; } + public DateTime Timestamp { get; set; } + public string UserId { get; set; } + public string DownloadUrl { get; set; } + } } \ No newline at end of file diff --git a/Project-Unite/Models/ManageViewModels.cs b/Project-Unite/Models/ManageViewModels.cs index 7a84bda..d8a1497 100644 --- a/Project-Unite/Models/ManageViewModels.cs +++ b/Project-Unite/Models/ManageViewModels.cs @@ -14,6 +14,12 @@ public class IndexViewModel public bool BrowserRemembered { get; set; } } + public class BackupViewModel + { + public IEnumerable Databases { get; set; } + public IEnumerable AssetFolders { get; set; } + } + public class ManageLoginsViewModel { public IList CurrentLogins { get; set; } diff --git a/Project-Unite/Project-Unite.csproj b/Project-Unite/Project-Unite.csproj index 34ecf81..7c03cf0 100644 --- a/Project-Unite/Project-Unite.csproj +++ b/Project-Unite/Project-Unite.csproj @@ -121,6 +121,8 @@ + + @@ -527,6 +529,7 @@ + diff --git a/Project-Unite/Views/Admin/Backups.cshtml b/Project-Unite/Views/Admin/Backups.cshtml new file mode 100644 index 0000000..313c2e7 --- /dev/null +++ b/Project-Unite/Views/Admin/Backups.cshtml @@ -0,0 +1,66 @@ +@model Project_Unite.Models.BackupViewModel +@{ + ViewBag.Title = "Backups"; +} + +

Backups

+ +

On this page you can request a backup of the current database and/or asset folder - or restore from a previous backup.

+ + + +
+
+

Databases

+

The database is what holds the bulk of the data on the ShiftOS site - forum posts, users, ACL rules, etc. Backing up the database can help in the case of spam, or a bug, or if you need to export the data to another software platform.

+ + + + + + + + @foreach(var backup in Model.Databases) + { + + + + + } +
BackupActions
@Html.UserLink(backup.UserId) on @backup.Timestamp + Download + @Html.ActionLink("Restore", "RestoreDatabaseBackup", new { id = backup.Id }); +
+
+
+

Asset folders

+

The asset folder is a dumping ground for user-created content hosted by ShiftOS. Avatars, profile backdrops, skins, game releases and other files not suited for storage within the database are put here.

+ +

User data is sorted by the site into folders named after the user. Backing this folder up can help in case the site's server goes down unexpectedly and cannot get back up and running - at least you have the user-created content and can bring it to a new server.

+ + + + + + + + @foreach (var backup in Model.AssetFolders) + { + + + + + } +
BackupActions
@Html.UserLink(backup.UserId) on @backup.Timestamp + Download + @Html.ActionLink("Restore", "RestoreAssetBackup", new { id = backup.Id }); +
+
+
\ No newline at end of file