|
| 1 | +// Licensed to the .NET Foundation under one or more agreements. |
| 2 | +// The .NET Foundation licenses this file to you under the MIT license. |
| 3 | +// See the LICENSE file in the project root for more information. |
| 4 | + |
| 5 | +using System; |
| 6 | +using System.Collections.ObjectModel; |
| 7 | +using System.Data; |
| 8 | +using Microsoft.Data.SqlClient.DataClassification; |
| 9 | +using Xunit; |
| 10 | + |
| 11 | +namespace Microsoft.Data.SqlClient.ManualTesting.Tests |
| 12 | +{ |
| 13 | + public static class DataClassificationTest |
| 14 | + { |
| 15 | + private static string s_tableName; |
| 16 | + |
| 17 | + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsSupportedDataClassification))] |
| 18 | + public static void TestDataClassificationResultSet() |
| 19 | + { |
| 20 | + s_tableName = DataTestUtility.GetUniqueNameForSqlServer("DC"); |
| 21 | + using (SqlConnection sqlConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) |
| 22 | + using (SqlCommand sqlCommand = sqlConnection.CreateCommand()) |
| 23 | + { |
| 24 | + try |
| 25 | + { |
| 26 | + sqlConnection.Open(); |
| 27 | + Assert.True(DataTestUtility.IsSupportedDataClassification()); |
| 28 | + CreateTable(sqlCommand); |
| 29 | + RunTestsForServer(sqlCommand); |
| 30 | + } |
| 31 | + finally |
| 32 | + { |
| 33 | + DataTestUtility.DropTable(sqlConnection, s_tableName); |
| 34 | + } |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | + private static void RunTestsForServer(SqlCommand sqlCommand) |
| 39 | + { |
| 40 | + sqlCommand.CommandText = "SELECT * FROM " + s_tableName; |
| 41 | + using (SqlDataReader reader = sqlCommand.ExecuteReader()) |
| 42 | + { |
| 43 | + VerifySensitivityClassification(reader); |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + private static void VerifySensitivityClassification(SqlDataReader reader) |
| 48 | + { |
| 49 | + if (null != reader.SensitivityClassification) |
| 50 | + { |
| 51 | + for (int columnPos = 0; columnPos < reader.SensitivityClassification.ColumnSensitivities.Count; |
| 52 | + columnPos++) |
| 53 | + { |
| 54 | + foreach (SensitivityProperty sp in reader.SensitivityClassification.ColumnSensitivities[columnPos].SensitivityProperties) |
| 55 | + { |
| 56 | + ReadOnlyCollection<InformationType> infoTypes = reader.SensitivityClassification.InformationTypes; |
| 57 | + Assert.Equal(3, infoTypes.Count); |
| 58 | + for (int i = 0; i < infoTypes.Count; i++) |
| 59 | + { |
| 60 | + VerifyInfoType(infoTypes[i], i + 1); |
| 61 | + } |
| 62 | + |
| 63 | + ReadOnlyCollection<Label> labels = reader.SensitivityClassification.Labels; |
| 64 | + Assert.Single(labels); |
| 65 | + VerifyLabel(labels[0]); |
| 66 | + |
| 67 | + if (columnPos == 1 || columnPos == 2 || columnPos == 6 || columnPos == 7) |
| 68 | + { |
| 69 | + VerifyLabel(sp.Label); |
| 70 | + VerifyInfoType(sp.InformationType, columnPos); |
| 71 | + } |
| 72 | + } |
| 73 | + } |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + private static void VerifyLabel(Label label) |
| 78 | + { |
| 79 | + Assert.True(label != null); |
| 80 | + Assert.Equal("L1", label.Id); |
| 81 | + Assert.Equal("PII", label.Name); |
| 82 | + } |
| 83 | + |
| 84 | + private static void VerifyInfoType(InformationType informationType, int i) |
| 85 | + { |
| 86 | + Assert.True(informationType != null); |
| 87 | + Assert.Equal(i == 1 ? "COMPANY" : (i == 2 ? "NAME" : "CONTACT"), informationType.Id); |
| 88 | + Assert.Equal(i == 1 ? "Company Name" : (i == 2 ? "Person Name" : "Contact Information"), informationType.Name); |
| 89 | + } |
| 90 | + |
| 91 | + private static void CreateTable(SqlCommand sqlCommand) |
| 92 | + { |
| 93 | + sqlCommand.CommandText = "CREATE TABLE " + s_tableName + " (" |
| 94 | + + "[Id] [int] IDENTITY(1,1) NOT NULL," |
| 95 | + + "[CompanyName] [nvarchar](40) NOT NULL," |
| 96 | + + "[ContactName] [nvarchar](50) NULL," |
| 97 | + + "[ContactTitle] [nvarchar](40) NULL," |
| 98 | + + "[City] [nvarchar](40) NULL," |
| 99 | + + "[CountryName] [nvarchar](40) NULL," |
| 100 | + + "[Phone] [nvarchar](30) MASKED WITH (FUNCTION = 'default()') NULL," |
| 101 | + + "[Fax] [nvarchar](30) MASKED WITH (FUNCTION = 'default()') NULL)"; |
| 102 | + sqlCommand.ExecuteNonQuery(); |
| 103 | + |
| 104 | + sqlCommand.CommandText = "ADD SENSITIVITY CLASSIFICATION TO " + s_tableName |
| 105 | + + ".CompanyName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Company Name', INFORMATION_TYPE_ID='COMPANY')"; |
| 106 | + sqlCommand.ExecuteNonQuery(); |
| 107 | + |
| 108 | + sqlCommand.CommandText = "ADD SENSITIVITY CLASSIFICATION TO " + s_tableName |
| 109 | + + ".ContactName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Person Name', INFORMATION_TYPE_ID='NAME')"; |
| 110 | + sqlCommand.ExecuteNonQuery(); |
| 111 | + |
| 112 | + sqlCommand.CommandText = "ADD SENSITIVITY CLASSIFICATION TO " + s_tableName |
| 113 | + + ".Phone WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT')"; |
| 114 | + sqlCommand.ExecuteNonQuery(); |
| 115 | + |
| 116 | + sqlCommand.CommandText = "ADD SENSITIVITY CLASSIFICATION TO " + s_tableName |
| 117 | + + ".Fax WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT')"; |
| 118 | + sqlCommand.ExecuteNonQuery(); |
| 119 | + |
| 120 | + // INSERT ROWS OF DATA |
| 121 | + sqlCommand.CommandText = "INSERT INTO " + s_tableName + " VALUES (@companyName, @contactName, @contactTitle, @city, @country, @phone, @fax)"; |
| 122 | + |
| 123 | + sqlCommand.Parameters.AddWithValue("@companyName", "Exotic Liquids"); |
| 124 | + sqlCommand.Parameters.AddWithValue("@contactName", "Charlotte Cooper"); |
| 125 | + sqlCommand.Parameters.AddWithValue("@contactTitle", ""); |
| 126 | + sqlCommand.Parameters.AddWithValue("city", "London"); |
| 127 | + sqlCommand.Parameters.AddWithValue("@country", "UK"); |
| 128 | + sqlCommand.Parameters.AddWithValue("@phone", "(171) 555-2222"); |
| 129 | + sqlCommand.Parameters.AddWithValue("@fax", ""); |
| 130 | + sqlCommand.ExecuteNonQuery(); |
| 131 | + |
| 132 | + sqlCommand.Parameters.Clear(); |
| 133 | + sqlCommand.Parameters.AddWithValue("@companyName", "New Orleans"); |
| 134 | + sqlCommand.Parameters.AddWithValue("@contactName", "Cajun Delights"); |
| 135 | + sqlCommand.Parameters.AddWithValue("@contactTitle", ""); |
| 136 | + sqlCommand.Parameters.AddWithValue("city", "New Orleans"); |
| 137 | + sqlCommand.Parameters.AddWithValue("@country", "USA"); |
| 138 | + sqlCommand.Parameters.AddWithValue("@phone", "(100) 555-4822"); |
| 139 | + sqlCommand.Parameters.AddWithValue("@fax", ""); |
| 140 | + sqlCommand.ExecuteNonQuery(); |
| 141 | + |
| 142 | + sqlCommand.Parameters.Clear(); |
| 143 | + sqlCommand.Parameters.AddWithValue("@companyName", "Grandma Kelly's Homestead"); |
| 144 | + sqlCommand.Parameters.AddWithValue("@contactName", "Regina Murphy"); |
| 145 | + sqlCommand.Parameters.AddWithValue("@contactTitle", ""); |
| 146 | + sqlCommand.Parameters.AddWithValue("@city", "Ann Arbor"); |
| 147 | + sqlCommand.Parameters.AddWithValue("@country", "USA"); |
| 148 | + sqlCommand.Parameters.AddWithValue("@phone", "(313) 555-5735"); |
| 149 | + sqlCommand.Parameters.AddWithValue("@fax", "(313) 555-3349"); |
| 150 | + sqlCommand.ExecuteNonQuery(); |
| 151 | + } |
| 152 | + |
| 153 | + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsSupportedDataClassification))] |
| 154 | + public static void TestDataClassificationBulkCopy() |
| 155 | + { |
| 156 | + var data = new DataTable("Company"); |
| 157 | + data.Columns.Add("CompanyId", typeof(Guid)); |
| 158 | + data.Columns.Add("CompanyName", typeof(string)); |
| 159 | + data.Columns.Add("Email", typeof(string)); |
| 160 | + data.Columns.Add("CompanyType", typeof(int)); |
| 161 | + |
| 162 | + data.Rows.Add(Guid.NewGuid(), "Company 1", "[email protected]", 1); |
| 163 | + data.Rows.Add(Guid.NewGuid(), "Company 2", "[email protected]", 1); |
| 164 | + data.Rows.Add(Guid.NewGuid(), "Company 3", "[email protected]", 1); |
| 165 | + |
| 166 | + var tableName = DataTestUtility.GetUniqueNameForSqlServer("DC"); |
| 167 | + |
| 168 | + using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) |
| 169 | + { |
| 170 | + connection.Open(); |
| 171 | + try |
| 172 | + { |
| 173 | + // Setup Table |
| 174 | + using (SqlCommand sqlCommand = connection.CreateCommand()) |
| 175 | + { |
| 176 | + sqlCommand.CommandText = $"CREATE TABLE {tableName} (" + |
| 177 | + $" [CompanyId] [uniqueidentifier] NOT NULL," + |
| 178 | + $" [CompanyName][nvarchar](255) NOT NULL," + |
| 179 | + $" [Email] [nvarchar](50) NULL," + |
| 180 | + $" [CompanyType] [int] not null," + |
| 181 | + $" CONSTRAINT[PK_Company] PRIMARY KEY CLUSTERED (" + |
| 182 | + $" [CompanyId] ASC" + |
| 183 | + $" ) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON[PRIMARY]" + |
| 184 | + $" ) ON[PRIMARY]"; |
| 185 | + sqlCommand.ExecuteNonQuery(); |
| 186 | + |
| 187 | + sqlCommand.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}.Email WITH (label = 'Confidential', label_id = 'c185460f-4e20-4b89-9876-ae95f07ba087', information_type = 'Contact Info', information_type_id = '5c503e21-22c6-81fa-620b-f369b8ec38d1');"; |
| 188 | + sqlCommand.ExecuteNonQuery(); |
| 189 | + } |
| 190 | + |
| 191 | + // Perform Bulk Insert |
| 192 | + using (var bulk = new SqlBulkCopy(connection)) |
| 193 | + { |
| 194 | + bulk.DestinationTableName = tableName; |
| 195 | + bulk.ColumnMappings.Add("CompanyId", "CompanyId"); |
| 196 | + bulk.ColumnMappings.Add("CompanyName", "CompanyName"); |
| 197 | + bulk.ColumnMappings.Add("Email", "Email"); |
| 198 | + bulk.ColumnMappings.Add("CompanyType", "CompanyType"); |
| 199 | + bulk.WriteToServer(data); |
| 200 | + } |
| 201 | + } |
| 202 | + finally |
| 203 | + { |
| 204 | + DataTestUtility.DropTable(connection, tableName); |
| 205 | + } |
| 206 | + } |
| 207 | + } |
| 208 | + } |
| 209 | +} |
0 commit comments