public async Task EncryptionResourceTokenAuthRestricted() { TestDoc testDoc = await EncryptionTests.CreateItemAsync(EncryptionTests.itemContainerCore, EncryptionTests.dekId, TestDoc.PathsToEncrypt); User restrictedUser = EncryptionTests.databaseCore.GetUser(Guid.NewGuid().ToString()); await EncryptionTests.databaseCore.CreateUserAsync(restrictedUser.Id); PermissionProperties restrictedUserPermission = await restrictedUser.CreatePermissionAsync( new PermissionProperties(Guid.NewGuid().ToString(), PermissionMode.All, EncryptionTests.itemContainer)); CosmosDataEncryptionKeyProvider dekProvider = new CosmosDataEncryptionKeyProvider(new TestKeyWrapProvider()); TestEncryptor encryptor = new TestEncryptor(dekProvider); (string endpoint, string _) = TestCommon.GetAccountInfo(); CosmosClient clientForRestrictedUser = new CosmosClientBuilder(endpoint, restrictedUserPermission.Token) .WithEncryptor(encryptor) .Build(); Database databaseForRestrictedUser = clientForRestrictedUser.GetDatabase(EncryptionTests.databaseCore.Id); Container containerForRestrictedUser = databaseForRestrictedUser.GetContainer(EncryptionTests.itemContainer.Id); await EncryptionTests.PerformForbiddenOperationAsync(() => dekProvider.InitializeAsync(databaseForRestrictedUser, EncryptionTests.keyContainer.Id), "CosmosDekProvider.InitializeAsync"); await EncryptionTests.PerformOperationOnUninitializedDekProviderAsync(() => dekProvider.DataEncryptionKeyContainer.ReadDataEncryptionKeyAsync(EncryptionTests.dekId), "DEK.ReadAsync"); await EncryptionTests.PerformOperationOnUninitializedDekProviderAsync(() => containerForRestrictedUser.ReadItemAsync <TestDoc>(testDoc.Id, new PartitionKey(testDoc.PK)), "ReadItemAsync"); await EncryptionTests.PerformOperationOnUninitializedDekProviderAsync(() => containerForRestrictedUser.ReadItemStreamAsync(testDoc.Id, new PartitionKey(testDoc.PK)), "ReadItemStreamAsync"); }
public static async Task ClassInitialize(TestContext context) { EncryptionTests.dekProvider = new CosmosDataEncryptionKeyProvider(new TestKeyWrapProvider()); EncryptionTests.encryptor = new TestEncryptor(EncryptionTests.dekProvider); EncryptionTests.client = EncryptionTests.GetClient(); EncryptionTests.databaseCore = (DatabaseInlineCore)await EncryptionTests.client.CreateDatabaseAsync(Guid.NewGuid().ToString()); EncryptionTests.keyContainer = await EncryptionTests.databaseCore.CreateContainerAsync(Guid.NewGuid().ToString(), "/id", 400); await EncryptionTests.dekProvider.InitializeAsync(EncryptionTests.databaseCore, EncryptionTests.keyContainer.Id); EncryptionTests.itemContainer = await EncryptionTests.databaseCore.CreateContainerAsync(Guid.NewGuid().ToString(), "/PK", 400); EncryptionTests.itemContainerCore = (ContainerInlineCore)EncryptionTests.itemContainer; EncryptionTests.dekProperties = await EncryptionTests.CreateDekAsync(EncryptionTests.dekProvider, EncryptionTests.dekId); }
public async Task ClassInitialize(TestContext context) { EncryptionContainerTests.dekProvider = new CosmosDataEncryptionKeyProvider(new TestKeyWrapProvider()); EncryptionContainerTests.encryptor = new TestEncryptor(EncryptionContainerTests.dekProvider); EncryptionContainerTests.client = TestCommon.CreateCosmosClient(); EncryptionContainerTests.database = await EncryptionContainerTests.client.CreateDatabaseAsync(Guid.NewGuid().ToString()); EncryptionContainerTests.keyContainer = await EncryptionContainerTests.database.CreateContainerAsync(Guid.NewGuid().ToString(), "/id", 400); await EncryptionContainerTests.dekProvider.InitializeAsync(EncryptionContainerTests.database, EncryptionContainerTests.keyContainer.Id); EncryptionContainerTests.itemContainer = await EncryptionContainerTests.database.CreateContainerAsync(Guid.NewGuid().ToString(), "/PK", 400); EncryptionContainerTests.propertyEncryptionContainer = EncryptionContainerTests.itemContainer.WithPropertyEncryptor(encryptor, EncryptionContainerTests.PathsToEncrypt); EncryptionContainerTests.pdekProperties = await EncryptionContainerTests.CreatePropertyDekAsync(EncryptionContainerTests.dekProvider, EncryptionContainerTests.pdekId); EncryptionContainerTests.twoPropertyEncryptionContainer = EncryptionContainerTests.itemContainer.WithPropertyEncryptor(encryptor, EncryptionContainerTests.PathsToEncrypt3); EncryptionContainerTests.twoPropertyOneDekEncryptionContainer = EncryptionContainerTests.itemContainer.WithPropertyEncryptor(encryptor, EncryptionContainerTests.PathsToEncrypt4); }
public async Task EncryptionResourceTokenAuthAllowed() { User keyManagerUser = EncryptionTests.databaseCore.GetUser(Guid.NewGuid().ToString()); await EncryptionTests.databaseCore.CreateUserAsync(keyManagerUser.Id); PermissionProperties keyManagerUserPermission = await keyManagerUser.CreatePermissionAsync( new PermissionProperties(Guid.NewGuid().ToString(), PermissionMode.All, EncryptionTests.keyContainer)); CosmosDataEncryptionKeyProvider dekProvider = new CosmosDataEncryptionKeyProvider(new TestKeyWrapProvider()); TestEncryptor encryptor = new TestEncryptor(dekProvider); (string endpoint, string _) = TestCommon.GetAccountInfo(); CosmosClient clientForKeyManagerUser = new CosmosClientBuilder(endpoint, keyManagerUserPermission.Token) .WithEncryptor(encryptor) .Build(); Database databaseForKeyManagerUser = clientForKeyManagerUser.GetDatabase(EncryptionTests.databaseCore.Id); await dekProvider.InitializeAsync(databaseForKeyManagerUser, EncryptionTests.keyContainer.Id); DataEncryptionKeyProperties readDekProperties = await dekProvider.DataEncryptionKeyContainer.ReadDataEncryptionKeyAsync(EncryptionTests.dekId); Assert.AreEqual(EncryptionTests.dekProperties, readDekProperties); }
/// <summary> /// To get a request without sending a push notification call this method. /// This method will throw an ArgumentException if there is an issue with the input. /// </summary> /// <param name="subscription">The PushSubscription you wish to send the notification to.</param> /// <param name="payload">The payload you wish to send to the user</param> /// <param name="options"> /// Options for the GCM API key and vapid keys can be passed in if they are unique for each /// notification. /// </param> /// <returns>A HttpRequestMessage object that can be sent.</returns> public HttpRequestMessage GenerateRequestDetails(PushSubscription subscription, string payload, Dictionary <string, object> options = null) { if (!Uri.IsWellFormedUriString(subscription.Endpoint, UriKind.Absolute)) { throw new ArgumentException(@"You must pass in a subscription with at least a valid endpoint"); } var request = new HttpRequestMessage(HttpMethod.Post, subscription.Endpoint); if (!string.IsNullOrEmpty(payload) && (string.IsNullOrEmpty(subscription.Auth) || string.IsNullOrEmpty(subscription.P256DH))) { throw new ArgumentException( @"To send a message with a payload, the subscription must have 'auth' and 'p256dh' keys."); } var currentGcmApiKey = _gcmApiKey; var currentVapidDetails = _vapidDetails; var timeToLive = DefaultTtl; var extraHeaders = new Dictionary <string, object>(); if (options != null) { var validOptionsKeys = new List <string> { "headers", "gcmAPIKey", "vapidDetails", "TTL" }; foreach (var key in options.Keys) { if (!validOptionsKeys.Contains(key)) { throw new ArgumentException(key + " is an invalid options. The valid options are" + string.Join(",", validOptionsKeys)); } } if (options.ContainsKey("headers")) { var headers = options["headers"] as Dictionary <string, object>; extraHeaders = headers ?? throw new ArgumentException("options.headers must be of type Dictionary<string,object>"); } if (options.ContainsKey("gcmAPIKey")) { var gcmApiKey = options["gcmAPIKey"] as string; currentGcmApiKey = gcmApiKey ?? throw new ArgumentException("options.gcmAPIKey must be of type string"); } if (options.ContainsKey("vapidDetails")) { var vapidDetails = options["vapidDetails"] as VapidDetails; currentVapidDetails = vapidDetails ?? throw new ArgumentException("options.vapidDetails must be of type VapidDetails"); } if (options.ContainsKey("TTL")) { var ttl = options["TTL"] as int?; if (ttl == null) { throw new ArgumentException("options.TTL must be of type int"); } //at this stage ttl cannot be null. timeToLive = (int)ttl; } } string cryptoKeyHeader = null; request.Headers.Add("TTL", timeToLive.ToString()); foreach (var header in extraHeaders) { request.Headers.Add(header.Key, header.Value.ToString()); } if (!string.IsNullOrEmpty(payload)) { if (string.IsNullOrEmpty(subscription.P256DH) || string.IsNullOrEmpty(subscription.Auth)) { throw new ArgumentException( @"Unable to send a message with payload to this subscription since it doesn't have the required encryption key"); } var encryptedPayload = TestEncryptor.Encrypt(subscription.P256DH, subscription.Auth, payload); request.Content = new ByteArrayContent(encryptedPayload.Payload); request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); request.Content.Headers.ContentLength = encryptedPayload.Payload.Length; request.Content.Headers.ContentEncoding.Add("aesgcm"); request.Headers.Add("Encryption", "salt=" + encryptedPayload.Base64EncodeSalt()); cryptoKeyHeader = @"dh=" + encryptedPayload.Base64EncodePublicKey(); } else { request.Content = new ByteArrayContent(new byte[0]); request.Content.Headers.ContentLength = 0; } var isGcm = subscription.Endpoint.StartsWith(@"https://android.googleapis.com/gcm/send"); var isFcm = subscription.Endpoint.StartsWith(@"https://fcm.googleapis.com/fcm/send/"); if (isGcm) { if (!string.IsNullOrEmpty(currentGcmApiKey)) { request.Headers.TryAddWithoutValidation("Authorization", "key=" + currentGcmApiKey); } } else if (currentVapidDetails != null) { var uri = new Uri(subscription.Endpoint); var audience = uri.Scheme + @"://" + uri.Host; var vapidHeaders = VapidHelper.GetVapidHeaders(audience, currentVapidDetails.Subject, currentVapidDetails.PublicKey, currentVapidDetails.PrivateKey, currentVapidDetails.Expiration); request.Headers.Add(@"Authorization", vapidHeaders["Authorization"]); if (string.IsNullOrEmpty(cryptoKeyHeader)) { cryptoKeyHeader = vapidHeaders["Crypto-Key"]; } else { cryptoKeyHeader += @";" + vapidHeaders["Crypto-Key"]; } } else if (isFcm && !string.IsNullOrEmpty(currentGcmApiKey)) { request.Headers.TryAddWithoutValidation("Authorization", "key=" + currentGcmApiKey); } request.Headers.Add("Crypto-Key", cryptoKeyHeader); return(request); }