diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..2a046ec Binary files /dev/null and b/.DS_Store differ diff --git a/WebAPI/.DS_Store b/WebAPI/.DS_Store new file mode 100644 index 0000000..01415a8 Binary files /dev/null and b/WebAPI/.DS_Store differ diff --git a/WebAPI/Controllers/AdminController.cs b/WebAPI/Controllers/AdminController.cs new file mode 100644 index 0000000..41ce1f6 --- /dev/null +++ b/WebAPI/Controllers/AdminController.cs @@ -0,0 +1,112 @@ +using System.Data; +using System.Globalization; +using System.Xml.Serialization; +using Google.Apis.Sheets.v4; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using WebAPI.dataParsers; +using WebAPI.Exports; +using WebAPI.Models; +using static Google.Apis.Drive.v3.FilesResource; + +namespace WebAPI.Controllers +{ + [ApiController] + [Route("api/[controller]")] + + public class AdminController : Controller + { + private readonly AppDbContext db; + private GoogleDriveHelper googleDriveHelper; + private GoogleSheetsHelper googleSheetsHelper; + private readonly IConfiguration configuration; + private readonly LogsController logsController; + + public AdminController( + AppDbContext _db, + GoogleSheetsHelper _googleSheetsHelper, + GoogleDriveHelper _googleDriveHelper, + IConfiguration _configuration) + { + db = _db; + googleSheetsHelper = _googleSheetsHelper; + googleDriveHelper = _googleDriveHelper; + configuration = _configuration; + logsController = new LogsController(googleSheetsHelper, googleDriveHelper, configuration); + } + + [HttpGet] + [Route("BackupDatabase/{apiKey}")] + [AllowAnonymous] + public IActionResult BackupDatabase(string apiKey) + { + if (Request.Host.Value != configuration["apiLocalUrl"] || apiKey != configuration["apiKey"]) + { + return Unauthorized(); + } + try + { + string databaseName = "diunabi-morska"; + string localDatabasePath = $"{configuration["dbBackupFile"]}-{DateTime.UtcNow.Day}.bak"; + var formatMediaName = $"DatabaseToolkitBackup_{databaseName}"; + var formatName = $"Full Backup of {databaseName}"; + + var connection = new SqlConnection(configuration.GetConnectionString("SQLDatabase")); + + var sql = @"BACKUP DATABASE @databaseName + TO DISK = @localDatabasePath + WITH FORMAT, + MEDIANAME = @formatMediaName, + NAME = @formatName"; + + connection.Open(); + var command = new SqlCommand(sql, connection); + + command.CommandType = CommandType.Text; + command.CommandTimeout = 7200; + command.Parameters.AddWithValue("@databaseName", databaseName); + command.Parameters.AddWithValue("@localDatabasePath", localDatabasePath); + command.Parameters.AddWithValue("@formatMediaName", formatMediaName); + command.Parameters.AddWithValue("@formatName", formatName); + + // command.ExecuteNonQuery(); + + Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File(); + body.Name = Path.GetFileName(localDatabasePath); + body.Parents = new List { configuration["GDriveBackupDirectory"] }; + body.MimeType = "application/octet-stream"; + + var fsSource = new FileStream(localDatabasePath, FileMode.Open, FileAccess.Read); + + CreateMediaUpload request = googleDriveHelper.Service.Files.Create(body, fsSource, body.MimeType); + request.Fields = "id"; + + var response = request.Upload(); + + + logsController.AddEntry(new LogEntry + { + Title = "Backup success", + Type = LogEntryType.info, + LogType = LogType.backup, + CreatedAt = DateTime.UtcNow + }); + return Ok(); + } + catch (Exception e) + { + logsController.AddEntry(new LogEntry + { + Title = "Backup error", + Type = LogEntryType.error, + LogType = LogType.backup, + Message = e.ToString(), + CreatedAt = DateTime.UtcNow + }); + return BadRequest(e.ToString()); + } + } + } +} \ No newline at end of file diff --git a/WebAPI/Controllers/LayersController.cs b/WebAPI/Controllers/LayersController.cs index 773240d..bf1ed94 100644 --- a/WebAPI/Controllers/LayersController.cs +++ b/WebAPI/Controllers/LayersController.cs @@ -165,6 +165,7 @@ namespace WebAPI.Controllers { Title = "Import error", Type = LogEntryType.error, + LogType = LogType.import, Message = e.ToString(), CreatedAt = DateTime.UtcNow }); @@ -294,9 +295,9 @@ namespace WebAPI.Controllers { Title = $"Import Success, {importWorker.Name}", Type = LogEntryType.info, + LogType = LogType.import, CreatedAt = DateTime.UtcNow }); - } private Layer AddLayer(Layer input, Guid currentUserId) { diff --git a/WebAPI/Controllers/LogsController.cs b/WebAPI/Controllers/LogsController.cs index 2e12bcf..46d64a9 100644 --- a/WebAPI/Controllers/LogsController.cs +++ b/WebAPI/Controllers/LogsController.cs @@ -29,6 +29,9 @@ namespace WebAPI.Controllers case LogType.import: type = "Import"; break; + case LogType.backup: + type = "Backup"; + break; default: type = "Other"; // should never happen break; diff --git a/WebAPI/Models/LogEntry.cs b/WebAPI/Models/LogEntry.cs index 5e0b970..a4d9193 100644 --- a/WebAPI/Models/LogEntry.cs +++ b/WebAPI/Models/LogEntry.cs @@ -9,7 +9,8 @@ namespace WebAPI.Models error, } public enum LogType { - import + import, + backup } public class LogEntry { diff --git a/WebAPI/appsettings.Development.json b/WebAPI/appsettings.Development.json index 8da826e..4786320 100644 --- a/WebAPI/appsettings.Development.json +++ b/WebAPI/appsettings.Development.json @@ -16,6 +16,8 @@ "exportDirectory": "1eTyCUzYbzVQB8f8sbNmvnebFXyW2-axt", "appLogsFile": "13PuDvS3_HAYoSLOCgKexzlzIDLUilkApUF8QiJMTae0", "apiLocalUrl": "localhost:5400", + "dbBackupFile": "/home/mz/backups/diunabi-morska", + "GDriveBackupDirectory": "1FEcdtVcF2cuqCROdq-vlBNs__th1M8_P", "Kestrel": { "Endpoints": { "Http": { diff --git a/WebAPI/appsettings.json b/WebAPI/appsettings.json index 900c42f..9c18f0f 100644 --- a/WebAPI/appsettings.json +++ b/WebAPI/appsettings.json @@ -13,9 +13,11 @@ "GoogleClientId": "#{google-backend-login-client-id}#", "Secret": "#{google-backend-login-secret}#", "apiKey": "#{api-key}#", - "exportDirectory": "#{export-directory}#", + "exportDirectory": "#{export-directory}#", "appLogsFile": "#{app-logs-file}#", "apiLocalUrl": "#{api-local-url}#", + "dbBackupFile": "#{db-backup-file}", + "GDriveBackupDirectory": "#{gdrive-backup-directory}", "Kestrel": { "Endpoints": { "Http": {