示例#1
0
        /// <summary>
        /// Get backup directory
        /// </summary>
        protected override string GetBackupDirectory(BackupMedia media)
        {
            switch (media)
            {
            case BackupMedia.Private:
                return(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData));

            case BackupMedia.Public:
                var ossec = (ApplicationContext.Current as AndroidApplicationContext).CurrentActivity as IOperatingSystemSecurityService;
                if (ossec.HasPermission(PermissionType.FileSystem) ||
                    ossec.RequestPermission(PermissionType.FileSystem))
                {
                    var retVal = System.IO.Path.Combine(
                        A.OS.Environment.ExternalStorageDirectory.AbsolutePath,
                        A.OS.Environment.DirectoryDocuments,
                        (AndroidApplicationContext.Current as AndroidApplicationContext).AndroidApplication.PackageName);
                    if (!System.IO.Directory.Exists(retVal))
                    {
                        System.IO.Directory.CreateDirectory(retVal);
                    }
                    return(retVal);
                }
                else
                {
                    return(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData));
                }

            default:
                throw new PlatformNotSupportedException("Don't support external media on this platform");
            }
        }
        /// <summary>
        /// Rremove t
        /// </summary>
        /// <param name="media"></param>
        /// <param name="backupDescriptor"></param>
        public void RemoveBackup(BackupMedia media, string backupDescriptor)
        {
            // Make a determination that the user is allowed to perform this action
            if (AuthenticationContext.Current.Principal != AuthenticationContext.SystemPrincipal)
            {
                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.ExportClinicalData).Demand();
            }

            var directoryName = this.GetBackupDirectory(media);

            this.m_tracer.TraceInfo("Removing backup {0}...", backupDescriptor);

            var expectedFile = Path.ChangeExtension(Path.Combine(directoryName, backupDescriptor), ".sdbk");

            if (!File.Exists(expectedFile))
            {
                throw new FileNotFoundException($"Cannot find backup with descriptor {backupDescriptor}");
            }
            else
            {
                try
                {
                    File.Delete(expectedFile);
                }
                catch (Exception)
                {
                    this.m_tracer.TraceError("Error removing backup descriptor {0}", backupDescriptor);
                    throw new Exception($"Error removing backup descriptor {backupDescriptor}");
                }
            }
        }
        /// <summary>
        /// Get backup directory
        /// </summary>
        protected virtual string GetBackupDirectory(BackupMedia media)
        {
            String retVal = String.Empty;

            switch (media)
            {
            case BackupMedia.Private:
                retVal = Path.Combine(ApplicationServiceContext.Current.GetService <IConfigurationPersister>().ApplicationDataDirectory, "backup");
                if (!Directory.Exists(retVal))
                {
                    Directory.CreateDirectory(retVal);
                }
                break;

            case BackupMedia.Public:
                retVal = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                // Sometimes my documents isn't available
                if (String.IsNullOrEmpty(retVal))
                {
                    retVal = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
                }
                break;

            default:
                throw new PlatformNotSupportedException("Don't support external media on this platform");
            }
            return(retVal);
        }
        /// <summary>
        /// Get the list of backup descriptors
        /// </summary>
        public IEnumerable <string> GetBackups(BackupMedia media)
        {
            var directoryName = this.GetBackupDirectory(media);

            this.m_tracer.TraceInfo("Getting {0} for backups...", directoryName);
            return(Directory.GetFiles(directoryName, "*.sdbk").OrderByDescending(o => new FileInfo(o).CreationTime).Select(o => Path.GetFileNameWithoutExtension(o)));
        }
        /// <summary>
        /// Get the last backup date
        /// </summary>
        private string GetLastBackup(BackupMedia media)
        {
            var directoryName = this.GetBackupDirectory(media);

            this.m_tracer.TraceInfo("Checking {0} for backups...", directoryName);
            System.Diagnostics.Trace.TraceInformation(directoryName);
            return(Directory.GetFiles(directoryName, "*.sdbk").OrderByDescending(o => o).FirstOrDefault());
        }
示例#6
0
        /// <summary>
        /// Get backup directory
        /// </summary>
        protected virtual string GetBackupDirectory(BackupMedia media)
        {
            switch (media)
            {
            case BackupMedia.Private:
                return(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));

            case BackupMedia.Public:
                return(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));

            default:
                throw new PlatformNotSupportedException("Don't support external media on this platform");
            }
        }
示例#7
0
        /// <summary>
        /// Returns a default location for tail log backup
        /// If the first backup media is from Microsoft Azure, a Microsoft Azure url for the Tail log backup file is returned
        /// </summary>
        internal string GetDefaultTailLogbackupFile(string databaseName, RestorePlan restorePlan)
        {
            if (string.IsNullOrEmpty(databaseName) || restorePlan == null)
            {
                return(string.Empty);
            }
            if (restorePlan.TailLogBackupOperation != null && restorePlan.TailLogBackupOperation.Devices != null)
            {
                restorePlan.TailLogBackupOperation.Devices.Clear();
            }
            string      folderpath       = string.Empty;
            BackupMedia firstBackupMedia = this.GetFirstBackupMedia(restorePlan);
            string      filename         = this.SanitizeFileName(databaseName) + "_LogBackup_" + this.GetServerCurrentDateTime().ToString("yyyy-MM-dd_HH-mm-ss") + ".bak";

            if (firstBackupMedia != null && firstBackupMedia.MediaType == DeviceType.Url)
            {
                // the uri will use the same container as the container of the first backup media
                Uri uri;
                if (Uri.TryCreate(firstBackupMedia.MediaName, UriKind.Absolute, out uri))
                {
                    UriBuilder uriBuilder = new UriBuilder();
                    uriBuilder.Scheme = uri.Scheme;
                    uriBuilder.Host   = uri.Host;
                    if (uri.AbsolutePath.Length > 0)
                    {
                        string[] parts   = uri.AbsolutePath.Split('/');
                        string   newPath = string.Join("/", parts, 0, parts.Length - 1);
                        if (newPath.EndsWith("/"))
                        {
                            newPath = newPath.Substring(0, newPath.Length - 1);
                        }
                        uriBuilder.Host = uriBuilder.Host + newPath;
                    }
                    uriBuilder.Path = filename;
                    string urlFilename = uriBuilder.Uri.AbsoluteUri;
                    if (restorePlan.TailLogBackupOperation != null && restorePlan.TailLogBackupOperation.Devices != null)
                    {
                        restorePlan.TailLogBackupOperation.Devices.Add(new BackupDeviceItem(urlFilename, DeviceType.Url));
                    }
                    return(urlFilename);
                }
            }
            folderpath = this.GetDefaultBackupFolder();
            if (restorePlan.TailLogBackupOperation != null && restorePlan.TailLogBackupOperation.Devices != null)
            {
                restorePlan.TailLogBackupOperation.Devices.Add(new BackupDeviceItem(PathWrapper.Combine(folderpath, filename), DeviceType.File));
            }
            return(PathWrapper.Combine(folderpath, filename));
        }
示例#8
0
        /// <summary>
        /// Restore the specified data
        /// </summary>
        public void Restore(BackupMedia media, String password = null)
        {
            // Get the last backup
            var lastBackup = this.GetLastBackup(media);

            if (!ApplicationContext.Current.Confirm(String.Format(Strings.locale_backup_restore_confirm, new FileInfo(lastBackup).CreationTime.ToString("ddd MMM dd, yyyy"))))
            {
                return;
            }

            try
            {
                this.m_tracer.TraceInfo("Beginning restore of {0}...", lastBackup);
                ApplicationContext.Current?.SetProgress(Strings.locale_backup_restore, 0.0f);
                var sourceDirectory = XamarinApplicationContext.Current.ConfigurationManager.ApplicationDataDirectory;

                using (var fs = File.OpenRead(lastBackup))
                    using (var gzs = new GZipStream(fs, CompressionMode.Decompress))
                        using (var tr = TarReader.Open(gzs))
                        {
                            // Move to next entry & copy
                            while (tr.MoveToNextEntry())
                            {
                                this.m_tracer.TraceVerbose("Extracting : {0}", tr.Entry.Key);
                                if (tr.Entry.Key == "DISCLAIMER.TXT" || tr.Entry.Key == ".appinfo.xml")
                                {
                                    continue;
                                }
                                var destDir = Path.Combine(sourceDirectory, tr.Entry.Key.Replace('/', Path.DirectorySeparatorChar));
                                if (!Directory.Exists(Path.GetDirectoryName(destDir)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(destDir));
                                }
                                if (!tr.Entry.IsDirectory)
                                {
                                    using (var s = tr.OpenEntryStream())
                                        using (var ofs = File.Create(Path.Combine(sourceDirectory, tr.Entry.Key)))
                                            s.CopyTo(ofs);
                                }
                            }
                        }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error restoring backup {0}: {1}", lastBackup, ex);
                throw;
            }
        }
        /// <summary>
        /// Restore the specified data
        /// </summary>
        public void Restore(BackupMedia media, String backupDescriptor = null, String password = null)
        {
            // Get the last backup
            String backupFile = null;

            if (String.IsNullOrEmpty(backupDescriptor))
            {
                backupFile = this.GetLastBackup(media);
            }
            else
            {
                if (!Path.IsPathRooted(backupDescriptor))
                {
                    var directoryName = this.GetBackupDirectory(media);
                    backupFile = Path.ChangeExtension(Path.Combine(directoryName, backupDescriptor), ".sdbk");
                }
                else
                {
                    backupFile = backupDescriptor;
                }
                if (!File.Exists(backupFile))
                {
                    throw new FileNotFoundException($"Cannot find backup with descriptor {backupDescriptor}");
                }
            }

            if (ApplicationContext.Current?.Confirm(String.Format(Strings.locale_backup_restore_confirm, new FileInfo(backupFile).CreationTime.ToString("ddd MMM dd, yyyy"))) == false)
            {
                return;
            }

            try
            {
                this.m_tracer.TraceInfo("Beginning restore of {0}...", backupFile);
                ApplicationContext.Current?.SetProgress(Strings.locale_backup_restore, 0.0f);
                var sourceDirectory = ApplicationContext.Current.ConfigurationPersister.ApplicationDataDirectory;
                this.RestoreFiles(backupFile, password, sourceDirectory);
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error restoring backup {0}: {1}", backupFile, ex);
                throw;
            }
        }
示例#10
0
        /// <summary>
        /// Get backup directory
        /// </summary>
        protected override string GetBackupDirectory(BackupMedia media)
        {
            switch (media)
            {
            case BackupMedia.Private:
                return(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData));

            case BackupMedia.Public:
                var retVal = System.IO.Path.Combine(
                    A.OS.Environment.ExternalStorageDirectory.AbsolutePath,
                    A.OS.Environment.DirectoryDocuments,
                    (AndroidApplicationContext.Current as AndroidApplicationContext).AndroidApplication.PackageName);
                if (!System.IO.Directory.Exists(retVal))
                {
                    System.IO.Directory.CreateDirectory(retVal);
                }
                return(retVal);

            default:
                throw new PlatformNotSupportedException("Don't support external media on this platform");
            }
        }
示例#11
0
        /// <summary>
        /// Perform backup on the specified media
        /// </summary>
        public void Backup(BackupMedia media, String password = null)
        {
            // Make a determination that the user is allowed to perform this action
            if (AuthenticationContext.Current.Principal != AuthenticationContext.SystemPrincipal)
            {
                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.ExportClinicalData).Demand();
            }

            // Get the output medium
            var    directoryName = this.GetBackupDirectory(media);
            string fileName      = Path.Combine(directoryName, $"oizdc-{DateTime.Now.ToString("yyyyMMddHHmm")}.oiz.tar");

            // Confirm if the user really really wants to backup
            if (String.IsNullOrEmpty(password) &&
                !ApplicationContext.Current.Confirm(Strings.locale_backup_confirm))
            {
                return;
            }

            // TODO: Audit the backup to the data to the central server
            AuditUtil.AuditDataExport();

            // Try to backup the data
            try
            {
                this.m_tracer.TraceInfo("Beginning backup to {0}..", fileName);
                ApplicationContext.Current?.SetProgress(Strings.locale_backup, 0.25f);
                // Backup folders first
                var sourceDirectory = XamarinApplicationContext.Current.ConfigurationManager.ApplicationDataDirectory;

                using (var fs = File.Create(fileName))
                    using (var writer = new SharpCompress.Writers.Tar.TarWriter(fs, new SharpCompress.Writers.WriterOptions(SharpCompress.Common.CompressionType.None)))
                    {
                        this.BackupDirectory(writer, sourceDirectory, sourceDirectory);

                        var appInfo = new ApplicationInfo(false).ToDiagnosticReport();
                        // Output appInfo
                        using (var ms = new MemoryStream()) {
                            XmlSerializer xsz = new XmlSerializer(appInfo.GetType());
                            xsz.Serialize(ms, appInfo);
                            ms.Flush();
                            ms.Seek(0, SeekOrigin.Begin);
                            writer.Write(".appinfo.xml", ms, DateTime.Now);
                        }

                        // Output declaration statement
                        using (var ms = new MemoryStream(Encoding.UTF8.GetBytes($"User {(AuthenticationContext.Current?.Principal?.Identity?.Name ?? "SYSTEM")} created this backup on {DateTime.Now}. The end user was asked to confirm this decision to backup and acknolwedges all responsibilities for guarding this file.")))
                            writer.Write("DISCLAIMER.TXT", ms, DateTime.Now);
                    }

                this.m_tracer.TraceInfo("Beginning compression {0}..", fileName);
                using (var fs = File.OpenRead(fileName))
                    using (var gzs = new GZipStream(File.Create(fileName + ".gz"), CompressionMode.Compress))
                    {
                        int    br     = 4096;
                        byte[] buffer = new byte[br];
                        while (br == 4096)
                        {
                            br = fs.Read(buffer, 0, 4096);
                            gzs.Write(buffer, 0, br);
                            ApplicationContext.Current?.SetProgress(Strings.locale_backup_compressing, (float)fs.Position / (float)fs.Length * 0.5f + 0.5f);
                        }
                    }
                File.Delete(fileName);
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error backing up to {0}: {1}", fileName, ex);
                throw;
            }
        }
示例#12
0
        /// <summary>
        /// Get the last backup date
        /// </summary>
        private string GetLastBackup(BackupMedia media)
        {
            var directoryName = this.GetBackupDirectory(media);

            return(Directory.GetFiles(directoryName, "*.oiz.tar.gz").OrderByDescending(o => o).FirstOrDefault());
        }
示例#13
0
 /// <summary>
 /// Determine if backup is available on the specified media
 /// </summary>
 public bool HasBackup(BackupMedia media)
 {
     return(this.GetLastBackup(media) != null);
 }
        /// <summary>
        /// Perform backup on the specified media
        /// </summary>
        public void Backup(BackupMedia media, String password = null)
        {
            // Make a determination that the user is allowed to perform this action
            if (AuthenticationContext.Current.Principal != AuthenticationContext.SystemPrincipal)
            {
                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.ExportClinicalData).Demand();
            }

            // Get the output medium
            var    directoryName = this.GetBackupDirectory(media);
            string fileName      = Path.Combine(directoryName, $"sdbdc-{DateTime.Now.ToString("yyyy-MM-dd-HH-mm")}.tar");

            // Confirm if the user really really wants to backup
            if (String.IsNullOrEmpty(password) &&
                !ApplicationContext.Current.Confirm(Strings.locale_backup_confirm))
            {
                return;
            }

            // TODO: Audit the backup to the data to the central server
            AuditUtil.AuditDataExport();

            // Try to backup the data
            try
            {
                this.m_tracer.TraceInfo("Beginning backup to {0}..", fileName);
                ApplicationContext.Current?.SetProgress(Strings.locale_backup, 0.25f);
                // Backup folders first
                var sourceDirectory = ApplicationContext.Current.ConfigurationPersister.ApplicationDataDirectory;
                try
                {
                    using (var fs = File.Create(fileName))
                        using (var writer = new SharpCompress.Writers.Tar.TarWriter(fs, new TarWriterOptions(SharpCompress.Common.CompressionType.None, true)))
                        {
                            this.BackupDirectory(writer, sourceDirectory, sourceDirectory);

                            var appInfo = new DiagnosticReport()
                            {
                                ApplicationInfo = new DiagnosticApplicationInfo(AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(o => o.DefinedTypes.Any(t => t.Name == "Program" || t.Name == "SplashActivity")) ?? typeof(SanteDBConfiguration).Assembly)
                            };

                            // Output appInfo
                            using (var ms = new MemoryStream())
                            {
                                XmlSerializer xsz = XmlModelSerializerFactory.Current.CreateSerializer(appInfo.GetType());
                                xsz.Serialize(ms, appInfo);
                                ms.Flush();
                                ms.Seek(0, SeekOrigin.Begin);
                                writer.Write(".appinfo.xml", ms, DateTime.Now);
                            }

                            // Output declaration statement
                            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes($"User {(AuthenticationContext.Current?.Principal?.Identity?.Name ?? "SYSTEM")} created this backup on {DateTime.Now}. The end user was asked to confirm this decision to backup and acknolwedges all responsibilities for guarding this file.")))
                                writer.Write("DISCLAIMER.TXT", ms, DateTime.Now);

                            // Output databases
                            var dcc = ApplicationServiceContext.Current.GetService <IDataManagementService>();
                            var dbBackupLocation = dcc.Backup("");
                            this.BackupDirectory(writer, dbBackupLocation, dbBackupLocation);
                            try
                            {
                                Directory.Delete(dbBackupLocation, true);
                            }
                            catch { }

                            // Now include the configuration file
                            // HACK: This is a total hack to support restore in place
                            if (!String.IsNullOrEmpty(password))
                            {
                                using (var ms = new MemoryStream())
                                {
                                    ApplicationServiceContext.Current.GetService <IConfigurationManager>().Configuration.Save(ms);
                                    ms.Seek(0, SeekOrigin.Begin);
                                    var config = SanteDBConfiguration.Load(ms); /// Load a new copy off the stream
                                    // Set the security system not to encrypt the device secret
                                    config.GetSection <SecurityConfigurationSection>().PlainTextSecret = true;
                                    using (var oms = new MemoryStream())
                                    {
                                        config.Save(oms);
                                        oms.Flush();
                                        oms.Seek(0, SeekOrigin.Begin);
                                        writer.Write("santedb.config", oms, DateTime.Now);
                                    }
                                }
                            }
                        }

                    this.m_tracer.TraceInfo("Beginning compression {0}..", fileName);

                    using (var fileStream = File.Create(Path.ChangeExtension(fileName, "sdbk")))
                    {
                        Stream outStream = fileStream;
                        try
                        {
                            // Write header
                            fileStream.Write(MAGIC, 0, MAGIC.Length);

                            // Encrypt
                            if (!String.IsNullOrEmpty(password))
                            {
                                fileStream.WriteByte(1);

                                var cryptProvider = AesCryptoServiceProvider.Create();
                                var passKey       = ASCIIEncoding.ASCII.GetBytes(password);
                                passKey           = Enumerable.Range(0, 32).Select(o => passKey.Length > o ? passKey[o] : (byte)0).ToArray();
                                cryptProvider.Key = passKey;

                                cryptProvider.GenerateIV();
                                fileStream.Write(BitConverter.GetBytes(cryptProvider.IV.Length), 0, 4);
                                fileStream.Write(cryptProvider.IV, 0, cryptProvider.IV.Length);
                                outStream = new CryptoStream(fileStream, cryptProvider.CreateEncryptor(), CryptoStreamMode.Write);
                            }
                            else
                            {
                                fileStream.WriteByte(0);
                            }
                            using (var fs = File.OpenRead(fileName))
                                using (var gzs = new GZipStream(outStream, CompressionMode.Compress))
                                {
                                    fs.CopyTo(gzs);
                                }
                        }
                        finally
                        {
                            if (outStream != fileStream)
                            {
                                outStream.Close();
                            }
                        }
                    }
                }
                finally
                {
                    File.Delete(fileName);
                }
            }
            catch (Exception ex)
            {
                this.m_tracer.TraceError("Error backing up to {0}: {1}", fileName, ex);
                throw;
            }
        }