public async Task EncryptionResourceTokenAuth() { User user = EncryptionTests.databaseCore.GetUser(Guid.NewGuid().ToString()); await EncryptionTests.databaseCore.CreateUserAsync(user.Id); PermissionProperties permission = await user.CreatePermissionAsync( new PermissionProperties(Guid.NewGuid().ToString(), PermissionMode.All, EncryptionTests.container)); TestDoc testDoc = await EncryptionTests.CreateItemAsync(EncryptionTests.containerCore, EncryptionTests.dekId, TestDoc.PathsToEncrypt); (string endpoint, string _) = TestCommon.GetAccountInfo(); CosmosClient resourceTokenBasedClient = new CosmosClientBuilder(endpoint, permission.Token) .WithEncryptionKeyWrapProvider(new TestKeyWrapProvider()) .Build(); DatabaseCore databaseForTokenClient = (DatabaseInlineCore)resourceTokenBasedClient.GetDatabase(EncryptionTests.databaseCore.Id); Container containerForTokenClient = databaseForTokenClient.GetContainer(EncryptionTests.container.Id); await EncryptionTests.PerformForbiddenOperationAsync(() => databaseForTokenClient.GetDataEncryptionKey(EncryptionTests.dekId).ReadAsync(), "DEK.ReadAsync"); await EncryptionTests.PerformForbiddenOperationAsync(() => containerForTokenClient.ReadItemAsync <TestDoc>(testDoc.Id, new PartitionKey(testDoc.PK)), "ReadItemAsync"); await EncryptionTests.PerformForbiddenOperationAsync(() => containerForTokenClient.ReadItemStreamAsync(testDoc.Id, new PartitionKey(testDoc.PK)), "ReadItemStreamAsync"); }
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 async Task CreateUserWithReadPermission() { // based on https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/UserManagement/UserManagementProgram.cs using (var client = new CosmosClient(_config["CosmosData_ConnectionString"])) { var database = client.GetDatabase(_config[CosmosDataDatabaseIdKey]); var container = client.GetContainer(_config[CosmosDataDatabaseIdKey], _config[CosmosDataContainerIdKey]); // Create a user User user1 = await database.UpsertUserAsync("readonly_user_test1"); // Create read permissions on the container PermissionProperties readPermission = new PermissionProperties( id: "Read", permissionMode: PermissionMode.Read, container: container); // Permissions token will be regenerated here with an expiry of 1 hour PermissionProperties permission = await user1.UpsertPermissionAsync(readPermission); // Save the permissions in a string variable _userWithReadPermissionToken = permission.Token; } }
// </RunDemoAsync> // <ValidateAllPermissionsForItem> private static async Task ValidateAllPermissionsForItem( string endpoint, string databaseName, Container container, User user, SalesOrder salesOrder) { // All Permissions on Doc1 for user1 PermissionProperties allPermissionForItem = new PermissionProperties( id: "permissionUserSaleOrder", permissionMode: PermissionMode.All, container: container, resourcePartitionKey: new PartitionKey(salesOrder.AccountNumber)); PermissionProperties allItemPermission = await user.CreatePermissionAsync(allPermissionForItem); // Create a new client with the generated token using (CosmosClient permissionClient = new CosmosClient(endpoint, allItemPermission.Token)) { Container permissionContainer = permissionClient.GetContainer(databaseName, container.Id); SalesOrder readSalesOrder = await permissionContainer.ReadItemAsync <SalesOrder>( salesOrder.Id, new PartitionKey(salesOrder.AccountNumber)); Console.WriteLine(); Console.WriteLine("Read item will all permission succeeded."); // Read sales order item readSalesOrder.OrderDate = DateTime.UtcNow; // Write sales order item await permissionContainer.UpsertItemAsync <SalesOrder>( readSalesOrder, new PartitionKey(salesOrder.AccountNumber)); Console.WriteLine("Upsert item will all permission succeeded."); //try iterate items should fail because the user only has access to single partition key //and therefore cannot access anything outside of that partition key value. try { using (FeedIterator <SalesOrder> itemIterator = permissionContainer.GetItemQueryIterator <SalesOrder>( "select * from T")) { while (itemIterator.HasMoreResults) { await itemIterator.ReadNextAsync(); throw new ApplicationException("Should never get here"); } } } catch (CosmosException ce) when(ce.StatusCode == System.Net.HttpStatusCode.Forbidden) { Console.WriteLine("Item query failed because user has access to only 1 partition"); } } }
// </ValidateAllPermissionsForItem> // <ValidateReadPermissions> private static async Task ValidateReadPermissions( string endpoint, string databaseName, Container container, User user) { // Read Permission on container for the user PermissionProperties readPermission = new PermissionProperties( id: "Read", permissionMode: PermissionMode.Read, container: container); PermissionProperties readContainerPermission = await user.CreatePermissionAsync(readPermission); // Create a new client with the generated token using (CosmosClient readClient = new CosmosClient(endpoint, readContainerPermission.Token)) { Container readContainer = readClient.GetContainer(databaseName, container.Id); //try read items should succeed because user1 was granted Read permission on container1 using (FeedIterator <SalesOrder> feedIterator = readContainer.GetItemQueryIterator <SalesOrder>()) { while (feedIterator.HasMoreResults) { FeedResponse <SalesOrder> salesOrders = await feedIterator.ReadNextAsync(); foreach (SalesOrder salesOrder in salesOrders) { Console.WriteLine(JsonConvert.SerializeObject(salesOrder)); } } } //try iterate databases should fail because the user has no Admin rights //but only read access to a single container and therefore //cannot access anything outside of that container. try { using (FeedIterator <DatabaseProperties> databaseIterator = readClient.GetDatabaseQueryIterator <DatabaseProperties>("select T.* from T")) { while (databaseIterator.HasMoreResults) { await databaseIterator.ReadNextAsync(); throw new ApplicationException("Should never get here"); } } } catch (CosmosException ce) when(ce.StatusCode == System.Net.HttpStatusCode.Forbidden) { Console.WriteLine("Database query failed because user has no admin rights"); } } }
public void MockContainerPermissionTest() { Mock <Database> database = new Mock <Database>(); database.Setup(d => d.Id).Returns("MockDatabase"); Mock <Container> container = new Mock <Container>(); container.Setup(c => c.Id).Returns("MockContainer"); container.Setup(c => c.Database).Returns(database.Object); PermissionProperties properties = new PermissionProperties("permissionId", PermissionMode.All, container.Object); Assert.AreEqual(properties.ResourceUri, $"dbs/{database.Object.Id}/colls/{container.Object.Id}"); }
static async Task Main(string[] args) { // Create new CosmosClient to communiciate with Azure Cosmos DB using (var cosmosClient = new CosmosClient(accountEndpoint, authKey)) { // Create new database Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync(databaseId); // Create new container Container container = await database.CreateContainerIfNotExistsAsync(containerId, partitionKey); for (int i = 0; i < 100; i++) { Console.WriteLine($"Run: {i}"); // This will complete successfully. var authKeyItemId = await CreateItemAsync(container); var authKeyItem = await ReadItemAsync(container, authKeyItemId); string userId = Guid.NewGuid().ToString(); UserResponse userResponse = await database.CreateUserAsync(userId); User user = userResponse.User; string permissionId = Guid.NewGuid().ToString(); PermissionProperties permissionProperties = new PermissionProperties(permissionId, PermissionMode.Read, container); PermissionResponse permissionResponse = await user.CreatePermissionAsync(permissionProperties); using (var tokenCosmosClient = new CosmosClient(accountEndpoint, permissionResponse.Resource.Token)) { var tokenContainer = tokenCosmosClient.GetContainer(databaseId, containerId); // This will fail. var tokenItemId = await CreateItemAsync(tokenContainer); // This will succeed. var tokenItem = await ReadItemAsync(tokenContainer, authKeyItemId); } } } }
/// <summary> /// Creates permissions and generates the token for the user. /// </summary> /// <param name="id">The user's id.</param> /// <returns>A populated <see cref="CosmosToken"/> instance.</returns> public async Task <CosmosToken> GetTokenForId(string id) { var database = _client.GetDatabase(LocationContext.SuperCode); var cosmosUser = await CreateOrReadUserAsync(database, id); var permissionId = $"Permission-{id}-blogs"; var container = database.GetContainer(nameof(LocationContext)); var permissions = new PermissionProperties( id: permissionId, permissionMode: PermissionMode.All, container: container); await cosmosUser.UpsertPermissionAsync(permissions); _logger.LogInformation("Permissions upsert for {user} successful.", id); var token = await cosmosUser.GetPermission(permissionId).ReadAsync(); return(new CosmosToken { Endpoint = _client.Endpoint.ToString(), Key = token.Resource.Token }); }
static async Task <CustomPermissionResponse> UpsertPermissionAsync(User user, string permissionId, int expiryInSeconds, ILogger log) { try { var partitionKey = new PartitionKey(permissionId); var permissionProperties = new PermissionProperties( permissionId, PermissionMode.All, //default to all. This should be derived from scope in future _container, partitionKey); var permissionResponse = await user.UpsertPermissionAsync(permissionProperties, expiryInSeconds); if (permissionResponse?.StatusCode == HttpStatusCode.OK || permissionResponse?.StatusCode == HttpStatusCode.Created) { if (!string.IsNullOrEmpty(permissionResponse?.Resource?.Token) && !string.IsNullOrEmpty(permissionResponse?.Resource?.Id)) { log.LogInformation($"Successful permission token generated for user {permissionId}"); return(new CustomPermissionResponse() { Id = permissionResponse.Resource.Id, Token = permissionResponse.Resource.Token, TokenExpiry = DateTimeOffset.UtcNow.Add(TimeSpan.FromSeconds(expiryInSeconds)), PartitionKey = permissionId }); } } throw new ResourceTokenBrokerException($"Unable to upsert permission for user. Token or Id is missing or invalid. Status code: {permissionResponse?.StatusCode}"); } catch (Exception ex) { throw new ResourceTokenBrokerException($"Unable to upsert new permission for user. Unhandled exception: {ex}"); } }
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); }
public async Task CRUDTest() { string containerId = Guid.NewGuid().ToString(); ContainerResponse containerResponse = await this.cosmosDatabase.CreateContainerAsync(containerId, "/id"); Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); string userId = Guid.NewGuid().ToString(); UserResponse userResponse = await this.cosmosDatabase.CreateUserAsync(userId); User user = userResponse.User; Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(userId, user.Id); string permissionId = Guid.NewGuid().ToString(); PermissionProperties permissionProperties = new PermissionProperties(permissionId, PermissionMode.Read, containerResponse.Container); PermissionResponse permissionResponse = await user.CreatePermissionAsync(permissionProperties); Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(permissionId, permissionResponse.Resource.Id); Assert.AreEqual(permissionProperties.PermissionMode, permissionResponse.Resource.PermissionMode); Assert.IsNotNull(permissionResponse.Resource.Token); SelflinkValidator.ValidatePermissionSelfLink(permissionResponse.Resource.SelfLink); PermissionProperties newPermissionProperties = new PermissionProperties(permissionId, PermissionMode.All, containerResponse.Container); permissionResponse = await user.GetPermission(permissionId).ReplaceAsync(newPermissionProperties); //Backend returns Created instead of OK Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(permissionId, permissionResponse.Resource.Id); Assert.AreEqual(newPermissionProperties.PermissionMode, permissionResponse.Resource.PermissionMode); SelflinkValidator.ValidatePermissionSelfLink(permissionResponse.Resource.SelfLink); permissionResponse = await user.GetPermission(permissionId).ReadAsync(); Assert.AreEqual(HttpStatusCode.OK, permissionResponse.StatusCode); Assert.AreEqual(permissionId, permissionResponse.Resource.Id); SelflinkValidator.ValidatePermissionSelfLink(permissionResponse.Resource.SelfLink); permissionResponse = await user.GetPermission(permissionId).DeleteAsync(); Assert.AreEqual(HttpStatusCode.NoContent, permissionResponse.StatusCode); try { permissionResponse = await user.GetPermission(permissionId).ReadAsync(); Assert.Fail(); } catch (CosmosException ex) { Assert.AreEqual(HttpStatusCode.NotFound, ex.StatusCode); } permissionId = Guid.NewGuid().ToString(); permissionProperties = new PermissionProperties(permissionId, PermissionMode.Read, containerResponse.Container); permissionResponse = await user.CreatePermissionAsync(permissionProperties); Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(permissionId, permissionResponse.Resource.Id); Assert.AreEqual(permissionProperties.PermissionMode, permissionResponse.Resource.PermissionMode); Assert.IsNotNull(permissionResponse.Resource.Token); newPermissionProperties = new PermissionProperties(permissionId, PermissionMode.All, containerResponse.Container); permissionResponse = await user.UpsertPermissionAsync(newPermissionProperties); Assert.AreEqual(HttpStatusCode.OK, permissionResponse.StatusCode); Assert.AreEqual(permissionId, permissionResponse.Resource.Id); Assert.AreEqual(newPermissionProperties.PermissionMode, permissionResponse.Resource.PermissionMode); }
public async Task ItemResourcePermissionTest() { //create user string userId = Guid.NewGuid().ToString(); UserResponse userResponse = await this.cosmosDatabase.CreateUserAsync(userId); Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(userId, userResponse.Resource.Id); User user = userResponse.User; //create resource string containerId = Guid.NewGuid().ToString(); ContainerResponse containerResponse = await this.cosmosDatabase.CreateContainerAsync(containerId, "/id"); Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); Container container = containerResponse.Container; string itemId = Guid.NewGuid().ToString(); PartitionKey partitionKey = new PartitionKey(itemId); ItemResponse <dynamic> itemRespnose = await container.CreateItemAsync <dynamic>(new { id = itemId }, partitionKey); Assert.AreEqual(HttpStatusCode.Created, itemRespnose.StatusCode); //create permission string permissionId = Guid.NewGuid().ToString(); PermissionProperties permissionProperties = new PermissionProperties(permissionId, PermissionMode.Read, container, partitionKey, itemId); PermissionResponse permissionResponse = await user.CreatePermissionAsync(permissionProperties); PermissionProperties permission = permissionResponse.Resource; Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(permissionId, permission.Id); Assert.AreEqual(permissionProperties.PermissionMode, permission.PermissionMode); //delete resource with PermissionMode.Read using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: null, resourceToken: permission.Token)) { Container tokenContainer = tokenCosmosClient.GetContainer(this.cosmosDatabase.Id, containerId); ItemResponse <dynamic> readPermissionItem = await tokenContainer.ReadItemAsync <dynamic>(itemId, partitionKey); Assert.AreEqual(itemId, readPermissionItem.Resource.id.ToString()); try { ItemResponse <dynamic> response = await tokenContainer.DeleteItemAsync <dynamic>( itemId, partitionKey); Assert.Fail(); } catch (CosmosException ex) { Assert.AreEqual(HttpStatusCode.Forbidden, ex.StatusCode); } } //update permission to PermissionMode.All permissionProperties = new PermissionProperties(permissionId, PermissionMode.All, container); permissionResponse = await user.GetPermission(permissionId).ReplaceAsync(permissionProperties); permission = permissionResponse.Resource; //delete resource with PermissionMode.All using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: null, resourceToken: permission.Token)) { using (FeedIterator <dynamic> feed = tokenCosmosClient .GetDatabase(this.cosmosDatabase.Id) .GetContainer(containerId) .GetItemQueryIterator <dynamic>(new QueryDefinition("select * from t"))) { while (feed.HasMoreResults) { FeedResponse <dynamic> response = await feed.ReadNextAsync(); Assert.IsNotNull(response); } } } }
public async Task ContainerPartitionResourcePermissionTest(ConnectionMode connectionMode) { CosmosClientOptions cosmosClientOptions = new CosmosClientOptions() { ConnectionMode = connectionMode }; CosmosClient cosmosClient = TestCommon.CreateCosmosClient(cosmosClientOptions); Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync("PermissionTest"); //create user string userId = Guid.NewGuid().ToString(); UserResponse userResponse = await database.CreateUserAsync(userId); Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(userId, userResponse.Resource.Id); User user = userResponse.User; //create resource string containerId = Guid.NewGuid().ToString(); ContainerResponse containerResponse = await database.CreateContainerAsync( id : containerId, partitionKeyPath : "/id"); Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); Container container = containerResponse.Container; // Create items to read ToDoActivity itemAccess = ToDoActivity.CreateRandomToDoActivity(); ToDoActivity itemNoAccess = ToDoActivity.CreateRandomToDoActivity(); await container.CreateItemAsync <ToDoActivity>( itemAccess, new PartitionKey(itemAccess.id)); await container.CreateItemAsync <ToDoActivity>( itemNoAccess, new PartitionKey(itemNoAccess.id)); //create permission string permissionId = Guid.NewGuid().ToString(); PartitionKey partitionKey = new PartitionKey(itemAccess.id); PermissionProperties permissionProperties = new PermissionProperties( permissionId, PermissionMode.Read, container, partitionKey); PermissionResponse permissionResponse = await user.CreatePermissionAsync(permissionProperties); PermissionProperties permission = permissionResponse.Resource; Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(permissionId, permission.Id); Assert.AreEqual(permissionProperties.PermissionMode, permission.PermissionMode); using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: cosmosClientOptions, resourceToken: permission.Token)) { Container tokenContainer = tokenCosmosClient.GetContainer(database.Id, containerId); await tokenContainer.ReadItemAsync <ToDoActivity>(itemAccess.id, new PartitionKey(itemAccess.id)); try { await tokenContainer.ReadItemAsync <ToDoActivity>(itemNoAccess.id, new PartitionKey(itemNoAccess.id)); Assert.Fail(); } catch (CosmosException ex) { Assert.AreEqual(HttpStatusCode.Forbidden, ex.StatusCode); } QueryRequestOptions queryRequestOptions = new QueryRequestOptions() { PartitionKey = new PartitionKey(itemAccess.id) }; FeedIterator <ToDoActivity> feedIterator = tokenContainer.GetItemQueryIterator <ToDoActivity>( queryText: "select * from T", requestOptions: queryRequestOptions); List <ToDoActivity> result = new List <ToDoActivity>(); while (feedIterator.HasMoreResults) { FeedResponse <ToDoActivity> toDoActivities = await feedIterator.ReadNextAsync(); result.AddRange(toDoActivities); } Assert.AreEqual(1, result.Count); // Test query with no service interop via gateway query plan to replicate x32 app ContainerInternal containerCore = (ContainerInlineCore)tokenContainer; MockCosmosQueryClient mock = new MockCosmosQueryClient( clientContext: containerCore.ClientContext, cosmosContainerCore: containerCore, forceQueryPlanGatewayElseServiceInterop: true); Container tokenGatewayQueryPlan = new ContainerInlineCore( containerCore.ClientContext, (DatabaseInternal)containerCore.Database, containerCore.Id, mock); FeedIterator <ToDoActivity> feedIteratorGateway = tokenGatewayQueryPlan.GetItemQueryIterator <ToDoActivity>( queryText: "select * from T", requestOptions: queryRequestOptions); List <ToDoActivity> resultGateway = new List <ToDoActivity>(); while (feedIteratorGateway.HasMoreResults) { FeedResponse <ToDoActivity> toDoActivities = await feedIteratorGateway.ReadNextAsync(); resultGateway.AddRange(toDoActivities); } Assert.AreEqual(1, resultGateway.Count); } }
public async Task ContainerResourcePermissionTest() { //create user string userId = Guid.NewGuid().ToString(); UserResponse userResponse = await this.cosmosDatabase.CreateUserAsync(userId); Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(userId, userResponse.Resource.Id); User user = userResponse.User; //create resource string containerId = Guid.NewGuid().ToString(); ContainerResponse containerResponse = await this.cosmosDatabase.CreateContainerAsync(containerId, "/id"); Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); Container container = containerResponse.Container; //create permission string permissionId = Guid.NewGuid().ToString(); PermissionProperties permissionProperties = new PermissionProperties(permissionId, PermissionMode.Read, container); PermissionResponse permissionResponse = await user.CreatePermissionAsync(permissionProperties); PermissionProperties permission = permissionResponse.Resource; Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(permissionId, permission.Id); Assert.AreEqual(permissionProperties.PermissionMode, permission.PermissionMode); //delete resource with PermissionMode.Read using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: null, resourceToken: permission.Token)) { try { ContainerResponse response = await tokenCosmosClient .GetDatabase(this.cosmosDatabase.Id) .GetContainer(containerId) .DeleteContainerAsync(); Assert.Fail(); } catch (CosmosException ex) { Assert.AreEqual(HttpStatusCode.Forbidden, ex.StatusCode); } } //update permission to PermissionMode.All permissionProperties = new PermissionProperties(permissionId, PermissionMode.All, container); permissionResponse = await user.GetPermission(permissionId).ReplaceAsync(permissionProperties); permission = permissionResponse.Resource; //delete resource with PermissionMode.All using (CosmosClient tokenCosmosClient = TestCommon.CreateCosmosClient(clientOptions: null, resourceToken: permission.Token)) { ContainerResponse response = await tokenCosmosClient .GetDatabase(this.cosmosDatabase.Id) .GetContainer(containerId) .DeleteContainerAsync(); Assert.AreEqual(HttpStatusCode.NoContent, response.StatusCode); } }
public async Task ValidateAzureKeyCredentialDirectModeUpdateAsync() { string authKey = ConfigurationManager.AppSettings["MasterKey"]; string endpoint = ConfigurationManager.AppSettings["GatewayEndpoint"]; AzureKeyCredential masterKeyCredential = new AzureKeyCredential(authKey); using (CosmosClient client = new CosmosClient( endpoint, masterKeyCredential)) { string databaseName = Guid.NewGuid().ToString(); try { Cosmos.Database database = client.GetDatabase(databaseName); ResponseMessage responseMessage = await database.ReadStreamAsync(); Assert.AreEqual(HttpStatusCode.NotFound, responseMessage.StatusCode); { // Random key: Next set of actions are expected to fail => 401 (UnAuthorized) masterKeyCredential.Update(Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()))); responseMessage = await database.ReadStreamAsync(); Assert.AreEqual(HttpStatusCode.Unauthorized, responseMessage.StatusCode); string diagnostics = responseMessage.Diagnostics.ToString(); Assert.IsTrue(diagnostics.Contains("AuthProvider LifeSpan InSec"), diagnostics.ToString()); } { // Resetting back to master key => 404 (NotFound) masterKeyCredential.Update(authKey); responseMessage = await database.ReadStreamAsync(); Assert.AreEqual(HttpStatusCode.NotFound, responseMessage.StatusCode); } // Test with resource token interchageability masterKeyCredential.Update(authKey); database = await client.CreateDatabaseAsync(databaseName); string containerId = Guid.NewGuid().ToString(); ContainerResponse containerResponse = await database.CreateContainerAsync(containerId, "/id"); Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); { // Resource token with ALL permissoin's string userId = Guid.NewGuid().ToString(); UserResponse userResponse = await database.CreateUserAsync(userId); Cosmos.User user = userResponse.User; Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(userId, user.Id); string permissionId = Guid.NewGuid().ToString(); PermissionProperties permissionProperties = new PermissionProperties(permissionId, Cosmos.PermissionMode.All, client.GetContainer(databaseName, containerId)); PermissionResponse permissionResponse = await database.GetUser(userId).CreatePermissionAsync(permissionProperties); Assert.AreEqual(HttpStatusCode.Created, permissionResponse.StatusCode); Assert.AreEqual(permissionId, permissionResponse.Resource.Id); Assert.AreEqual(Cosmos.PermissionMode.All, permissionResponse.Resource.PermissionMode); Assert.IsNotNull(permissionResponse.Resource.Token); SelflinkValidator.ValidatePermissionSelfLink(permissionResponse.Resource.SelfLink); // Valdiate ALL on contianer masterKeyCredential.Update(permissionResponse.Resource.Token); ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(); Cosmos.Container container = client.GetContainer(databaseName, containerId); responseMessage = await container.ReadContainerStreamAsync(); Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode); responseMessage = await container.CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(item), new Cosmos.PartitionKey(item.id)); Assert.AreEqual(HttpStatusCode.Created, responseMessage.StatusCode); // Read Only resorce token } // Reset to master key for new permission creation masterKeyCredential.Update(authKey); { // Resource token with Read-ONLY permissoin's string userId = Guid.NewGuid().ToString(); UserResponse userResponse = await database.CreateUserAsync(userId); Cosmos.User user = userResponse.User; Assert.AreEqual(HttpStatusCode.Created, userResponse.StatusCode); Assert.AreEqual(userId, user.Id); string permissionId = Guid.NewGuid().ToString(); PermissionProperties permissionProperties = new PermissionProperties(permissionId, Cosmos.PermissionMode.Read, client.GetContainer(databaseName, containerId)); PermissionResponse permissionResponse = await database.GetUser(userId).CreatePermissionAsync(permissionProperties); //Backend returns Created instead of OK Assert.AreEqual(HttpStatusCode.Created, permissionResponse.StatusCode); Assert.AreEqual(permissionId, permissionResponse.Resource.Id); Assert.AreEqual(Cosmos.PermissionMode.Read, permissionResponse.Resource.PermissionMode); // Valdiate read on contianer masterKeyCredential.Update(permissionResponse.Resource.Token); ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(); Cosmos.Container container = client.GetContainer(databaseName, containerId); responseMessage = await container.ReadContainerStreamAsync(); Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode); responseMessage = await container.CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(item), new Cosmos.PartitionKey(item.id)); Assert.AreEqual(HttpStatusCode.Forbidden, responseMessage.StatusCode); // Read Only resorce token } { // Reset to master key for new permission creation masterKeyCredential.Update(Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()))); ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(); Cosmos.Container container = client.GetContainer(databaseName, containerId); responseMessage = await container.CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(item), new Cosmos.PartitionKey(item.id)); Assert.AreEqual(HttpStatusCode.Unauthorized, responseMessage.StatusCode); // Read Only resorce token string diagnostics = responseMessage.Diagnostics.ToString(); Assert.IsTrue(diagnostics.Contains("AuthProvider LifeSpan InSec"), diagnostics.ToString()); } } finally { // Reset to master key for clean-up masterKeyCredential.Update(authKey); await TestCommon.DeleteDatabaseAsync(client, client.GetDatabase(databaseName)); } } }
// </Main> // <RunDemoAsync> private static async Task RunDemoAsync( CosmosClient client, Database database) { //-------------------------------------------------------------------------------------------------- // We need Two Containers, Two Users, and some permissions for this sample, // So let's go ahead and set these up initially //-------------------------------------------------------------------------------------------------- // Get, or Create, two separate Containers Container container1 = await database.CreateContainerAsync( id : "Container1", partitionKeyPath : "/AccountNumber"); Container container2 = await database.CreateContainerAsync( id : "Container2", partitionKeyPath : "/AccountNumber"); // Insert two documents in to col1 SalesOrder salesOrder1 = new SalesOrder() { Id = "order1", AccountNumber = "partitionKey1" }; await container1.CreateItemAsync <SalesOrder>( salesOrder1, new PartitionKey(salesOrder1.AccountNumber)); SalesOrder salesOrder2 = new SalesOrder() { Id = "order2", AccountNumber = "pk2" }; await container1.CreateItemAsync <SalesOrder>( salesOrder2, new PartitionKey(salesOrder2.AccountNumber)); // Create a user User user1 = await database.CreateUserAsync("Thomas Andersen"); // Get an existing user and permission. // This is a client side reference and does no verification against Cosmos DB. user1 = database.GetUser("Thomas Andersen"); // Verify the user exists UserProperties userProperties = await user1.ReadAsync(); //Add the read permission to the user and validate the user can //read only the container it has access to await ValidateReadPermissions( client.Endpoint.OriginalString, database.Id, container1, user1); // Insert one item in to container 2 SalesOrder salesOrder3 = new SalesOrder() { Id = "doc3", AccountNumber = "partitionKey" }; await container2.CreateItemAsync <SalesOrder>( salesOrder3, new PartitionKey(salesOrder3.AccountNumber)); // Create a new user User user2 = await database.CreateUserAsync("Robin Wakefield"); //Add the all permission to the user for a single item and validate the user can //only access the single item await ValidateAllPermissionsForItem( client.Endpoint.OriginalString, database.Id, container2, user2, salesOrder3); // Add read permission to user1 on container 2 so query has multiple results PermissionResponse permissionUser1Container2Response = await user1.CreatePermissionAsync( new PermissionProperties( id : "permissionUser1Container2", permissionMode : PermissionMode.Read, container : container2)); Permission permissionUser1Container2 = permissionUser1Container2Response; PermissionProperties user1Container2Properties = permissionUser1Container2Response; Console.WriteLine(); Console.WriteLine($"Created {permissionUser1Container2.Id} with resource URI: {user1Container2Properties.ResourceUri}"); // Get an existing permission and token permissionUser1Container2 = user1.GetPermission("permissionUser1Container2"); // Get an existing permission properties user1Container2Properties = await permissionUser1Container2.ReadAsync(); Console.WriteLine($"Read existing {permissionUser1Container2.Id} with resource URI: {user1Container2Properties.ResourceUri}"); // All user1's permissions in a List List <PermissionProperties> user1Permissions = new List <PermissionProperties>(); FeedIterator <PermissionProperties> feedIterator = user1.GetPermissionQueryIterator <PermissionProperties>(); while (feedIterator.HasMoreResults) { FeedResponse <PermissionProperties> permissions = await feedIterator.ReadNextAsync(); user1Permissions.AddRange(permissions); } }