Beispiel #1
0
        public void TestAccessPermissions()
        {
            // var (testPath, numFiles) = prepareExampleDirectory();
            var(testPath, numFiles) = (_testPath, _numFiles);

            // Additional temporary folder without read permissions
            var subPath2     = Path.Combine(testPath, "sub2");
            var forbiddenDir = Directory.CreateDirectory(subPath2);

            // Additional temporary folder with ordinary permissions
            var subPath3 = Path.Combine(testPath, "sub3");

            Directory.CreateDirectory(subPath3);

            string       srcPath  = Path.Combine("TestData", "snapshot-test", "WMR");
            const string srcFile1 = "MyBasic.structuredefinition.xml";
            const string srcFile2 = "MyBundle.structuredefinition.xml";

            const string profileUrl1 = @"http://example.org/fhir/StructureDefinition/MyBasic";
            const string profileUrl2 = @"http://example.org/fhir/StructureDefinition/MyBundle";

            // Create test file in inaccessible subfolder; should be ignored
            copy(srcPath, srcFile1, subPath2);

            // Create hidden test file in accessible subfolder; should also be ignored
            copy(srcPath, srcFile1, subPath3);
            var filePath = Path.Combine(subPath3, srcFile1);
            var attr     = File.GetAttributes(filePath);

            File.SetAttributes(filePath, attr | FileAttributes.Hidden);

            // Create regular test file in accessible subfolder; should be included
            copy(srcPath, srcFile2, subPath3);
            numFiles++;

            bool initialized = false;

            try
            {
                // Abort unit test if we can't access folder permissions
                var ds = forbiddenDir.GetAccessControl();

                // Revoke folder read permissions for the current user
                string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
                var    rule     = new ssac.FileSystemAccessRule(userName, ssac.FileSystemRights.Read, ssac.AccessControlType.Deny);
                ds.AddAccessRule(rule);
                Debug.Print($"Removing read permissions from folder: '{subPath2}' ...");

                // Abort unit test if we can't modify file permissions
                forbiddenDir.SetAccessControl(ds);

                try
                {
                    var forbiddenFile = new FileInfo(Path.Combine(subPath2, srcFile1));

                    // Abort unit test if we can't access file permissions
                    var fs = forbiddenFile.GetAccessControl();

                    // Revoke file read permissions for the current user
                    fs.AddAccessRule(rule);
                    Debug.Print($"Removing read permissions from fole: '{forbiddenFile}' ...");

                    // Abort unit test if we can't modify file permissions
                    forbiddenFile.SetAccessControl(fs);

                    initialized = true;

                    try
                    {
                        // Note: we still have write permissions...

                        var dirSource = new DirectorySource(testPath, new DirectorySourceSettings()
                        {
                            IncludeSubDirectories = true
                        });

                        // [WMR 20170823] Test ListArtifactNames => prepareFiles()
                        var names = dirSource.ListArtifactNames();

                        Assert.AreEqual(numFiles, names.Count());
                        Assert.IsFalse(names.Contains(srcFile1));
                        Assert.IsTrue(names.Contains(srcFile2));

                        // [WMR 20170823] Also test ListResourceUris => prepareResources()
                        var profileUrls = dirSource.ListResourceUris(ResourceType.StructureDefinition);

                        // Materialize the sequence
                        var urlList = profileUrls.ToList();
                        Assert.IsFalse(urlList.Contains(profileUrl1));
                        Assert.IsTrue(urlList.Contains(profileUrl2));
                    }
                    // API *should* grafecully handle security exceptions
                    catch (UnauthorizedAccessException ex)
                    {
                        Assert.Fail($"Failed! Unexpected UnauthorizedAccessException: {ex.Message}");
                    }
                    finally
                    {
                        var result = fs.RemoveAccessRule(rule);
                        Assert.IsTrue(result);
                        Debug.Print($"Restoring file read permissions...");
                        forbiddenFile.SetAccessControl(fs);
                        Debug.Print($"Succesfully restored file read permissions.");

                        // We should be able to delete the file
                        File.Delete(forbiddenFile.FullName);
                    }
                }
                finally
                {
                    var result = ds.RemoveAccessRule(rule);
                    Assert.IsTrue(result);
                    Debug.Print($"Restoring folder read permissions...");
                    forbiddenDir.SetAccessControl(ds);
                    Debug.Print($"Succesfully restored folder read permissions.");

                    // We should be able to delete the subdirectory
                    Directory.Delete(subPath2, true);
                }
            }
            // If acl initialization failed, then consume the exception and return success
            // Preferably, skip this unit test / return unknown result - how?
            catch (Exception ex) when(!initialized)
            {
                Debug.Print($"[{nameof(TestAccessPermissions)}] Could not modify directory access permissions: '{ex.Message}'. Skip unit test...");
            }
        }