コード例 #1
0
        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");
        }
コード例 #2
0
        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");
        }
コード例 #3
0
        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;
            }
        }
コード例 #4
0
        // </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");
                }
            }
        }
コード例 #5
0
        // </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");
                }
            }
        }
コード例 #6
0
        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}");
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: rjygraham/CosmosDBDemo
        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);
                    }
                }
            }
        }
コード例 #8
0
        /// <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
            });
        }
コード例 #9
0
        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}");
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
                    }
                }
            }
        }
コード例 #13
0
        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);
            }
        }
コード例 #14
0
        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);
            }
        }
コード例 #15
0
        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));
                }
            }
        }
コード例 #16
0
        // </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);
            }
        }