static async Task <Permission> GetReadPermission(string userId, DocumentClient client, string databaseId, string collectionId)
        {
            Permission collectionPermission = new Permission();

            try
            {
                var collectionPermissionId = $"{userId}-publoc";
                collectionPermission = await client.ReadPermissionAsync(UriFactory.CreatePermissionUri(databaseId, userId, collectionPermissionId));
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    // The permission was not found - either the user (and permission) doesn't exist or permission doesn't exist
                    await CreateUserIfNotExistAsync(userId, client, databaseId);

                    var newPermission = new Permission
                    {
                        PermissionMode = PermissionMode.Read,
                        Id             = $"{userId}-publoc",
                        ResourceLink   = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId).ToString()
                    };

                    collectionPermission = await client.CreatePermissionAsync(UriFactory.CreateUserUri(databaseId, userId), newPermission);
                }
                else
                {
                    throw ex;
                }
            }

            return(collectionPermission);
        }
Esempio n. 2
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            ConnectionPolicy connectionPolicy = new ConnectionPolicy
            {
                EnableEndpointDiscovery = false,
                ConnectionMode          = ConnectionMode.Direct
            };
            // Uri serviceEndpoint = new Uri("https://contoso.documents.azure.com:443/");
            string         hostname        = File.ReadAllText(@"C:\apikeys\cosmos-db-gremlin\hostname.txt");
            Uri            serviceEndpoint = new Uri(hostname);
            string         authKey         = File.ReadAllText(@"C:\apikeys\cosmos-db-gremlin\authKey.txt");
            DocumentClient client          = new DocumentClient(serviceEndpoint, authKey, connectionPolicy);

            // Read specific permission to obtain a token.
            // The token isn't returned during the ReadPermissionReedAsync() call.
            // The call succeeds only if database id, user id, and permission id already exist.
            // Note that <database id> is not a database name. It is a base64 string that represents the database identifier, for example "KalVAA==".
            // Similar comment applies to <user id> and <permission id>.
            try
            {
                Permission permission = await client.ReadPermissionAsync(UriFactory.CreatePermissionUri("<database id>", "<user id>", "<permission id>"));

                Console.WriteLine("Obtained token {0}", permission.Token);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadLine();
        }
        static private async Task <string> CreateToken(string endpointUrl, string key)
        {
            var databaseName       = "ToDoList";
            var databaseCollection = "Items";

            var userName = "******";

            client = new DocumentClient(new Uri(endpointUrl), key);
            var db = await client.GetDatabaseAccountAsync();

            Database database = await client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(databaseName));

            User user = await CreateUserIfNotExistAsync(databaseName, userName);

            Permission docPermission = new Permission
            {
                PermissionMode = PermissionMode.Read,
                ResourceLink   = UriFactory.CreateDocumentCollectionUri(databaseName, databaseCollection).ToString(),
                Id             = "readperm"
            };

            var requestOptions = new RequestOptions()
            {
                ResourceTokenExpirySeconds = 8 * 3600
            };

            try {
                docPermission = await client.ReadPermissionAsync(UriFactory.CreatePermissionUri(databaseName, userName, docPermission.Id), requestOptions);
            }
            catch {
                docPermission = await client.CreatePermissionAsync(UriFactory.CreateUserUri(databaseName, userName), docPermission, requestOptions);
            }

            return(docPermission.Token.ToString());
        }
Esempio n. 4
0
        public void Delete(User user, Permission permission, string databaseId)
        {
            var permissionDeleteTask = Client.DeletePermissionAsync(UriFactory.CreatePermissionUri(
                                                                        databaseId,
                                                                        user.Id,
                                                                        permission.Id));

            permissionDeleteTask.Wait();
        }
        // ReSharper disable once UnusedMember.Local
        private static async Task DeletePermission(IDocumentClient client, User user, string permissionId)
        {
            Console.WriteLine($">>> Delete Permission {permissionId} from {user.Id} <<<");

            Uri permUri = UriFactory.CreatePermissionUri("mydb", "mystore", permissionId);
            await client.DeletePermissionAsync(permUri);

            Console.WriteLine("Deleted permission {permId} from user {user.Id}");
        }
        static async Task <Permission> GetPartitionPermission(string userId, DocumentClient client, string databaseId, string collectionId)
        {
            Permission partitionPermission = new Permission();
            bool       isLimitedPartition  = true;
            string     permissionId        = "";

            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
            Uri userUri       = UriFactory.CreateUserUri(databaseId, userId);

            if (userId == publicUserId)
            {
                permissionId       = $"{userId}-partition-limited-{collectionId}";
                isLimitedPartition = true;
            }
            else
            {
                permissionId       = $"{userId}-partition-all-{collectionId}";
                isLimitedPartition = false;
            }

            try
            {
                // the permission ID's format: {userID}-{documentID}
                Uri permissionUri = UriFactory.CreatePermissionUri(databaseId, userId, permissionId);

                partitionPermission = await client.ReadPermissionAsync(permissionUri);
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    // The permission was not found - either the user (and permission) doesn't exist or permission doesn't exist
                    await CreateUserIfNotExistAsync(userId, client, databaseId);

                    var newPermission = new Permission
                    {
                        PermissionMode = PermissionMode.Read,
                        Id             = permissionId,
                        ResourceLink   = collectionUri.ToString()
                    };

                    if (isLimitedPartition)
                    {
                        newPermission.ResourcePartitionKey = new PartitionKey(false);
                    }

                    partitionPermission = await client.CreatePermissionAsync(userUri, newPermission);
                }
                else
                {
                    throw ex;
                }
            }

            return(partitionPermission);
        }
Esempio n. 7
0
        private static async Task DeletePermissionAsync(DocumentClient client, User user, Permission permId)
        {
            Console.WriteLine();
            Console.WriteLine($">>> Delete Permission {permId.Id} from {user.Id} <<<");

            var permUri = UriFactory.CreatePermissionUri("FamiliesDb", "mystore", permId.Id);
            await client.DeletePermissionAsync(permUri);

            Console.WriteLine("Deleted permission {permId} from user {user.Id}");
        }
Esempio n. 8
0
        static async Task <Permission> GetPartitionPermission(string userId, DocumentClient client, string databaseId, string collectionId, ILogger log)
        {
            var        permissionId = userId;
            Permission partitionPermission;

            Uri permissionUri = UriFactory.CreatePermissionUri(databaseId, userId, permissionId);
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);

            try
            {
                partitionPermission = await client.ReadPermissionAsync(permissionUri);

                log.LogInformation("Found partition permission");

                return(partitionPermission);
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    await CreateUserIfNotExistAsync(userId, client, databaseId);
                }
            }

            Uri userUri = UriFactory.CreateUserUri(databaseId, userId);

            string partitionKeyValue;

            Permission     newPermission  = null;
            PermissionMode permissionMode = PermissionMode.Read;

            if (userId == PublicUser)
            {
                partitionKeyValue = PublicUser;
                permissionMode    = PermissionMode.Read;
            }
            else
            {
                partitionKeyValue = $"user-{userId}";
                permissionMode    = PermissionMode.All;
            }

            newPermission = new Permission
            {
                PermissionMode       = permissionMode,
                Id                   = permissionId,
                ResourceLink         = collectionUri.ToString(),
                ResourcePartitionKey = new PartitionKey(partitionKeyValue)
            };

            partitionPermission = await client.CreatePermissionAsync(userUri, newPermission);

            return(partitionPermission);
        }
        //TODO: maybe instead of for accepting a collection here, just take in one by one
        private async Task <List <Permission> > GetReadOnlyCollectionPermissions(string userId, List <string> collectionNames)
        {
            List <Permission> collectionPermissions = new List <Permission>();

            foreach (var collName in collectionNames)
            {
                Permission collPermission = new Permission();
                try
                {
                    // permission names are unique to the user
                    var collPermissionId = $"{userId}-{collName}";

                    // Read the permission from Cosmos (will throw a 404 if it doesn't exist)
                    collPermission = await Client.ReadPermissionAsync(UriFactory.CreatePermissionUri(databaseId, userId, collPermissionId));
                }
                catch (DocumentClientException dcx)
                {
                    if (dcx.StatusCode == HttpStatusCode.NotFound)
                    {
                        // Permission doesn't exist. First make sure the user exists
                        await CreateUserIfNotExistAsync(userId);

                        // New up a permissions for that user
                        var newPermission = new Permission
                        {
                            PermissionMode = PermissionMode.Read,
                            Id             = $"{userId}-{collName}",
                            ResourceLink   = UriFactory.CreateDocumentCollectionUri(databaseId, collName).ToString()
                        };

                        collPermission = await Client.CreatePermissionAsync(UriFactory.CreateUserUri(databaseId, userId), newPermission);
                    }
                    else
                    {
                        throw dcx;
                    }
                }

                // Add a document of this permission to Cosmos for caching reasons (so we don't have to grab it if it hasn't expired)
                var expires         = Convert.ToInt32(DateTime.UtcNow.Subtract(BeginningOfTime).TotalSeconds) + 3600;
                var permissionToken = new CollectionPermissionToken
                {
                    Expires              = expires,
                    UserId               = userId,
                    ResourceId           = collName,
                    SerializedPermission = SerializePermission(collPermission)
                };
                await CacheUserCollectionToken(permissionToken);

                collectionPermissions.Add(collPermission);
            }

            return(collectionPermissions);
        }
Esempio n. 10
0
        /// <summary>
        /// Removes a permission
        /// <para/>Note: Should only be called from a mid-tier service.
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="permissionId"></param>
        /// <param name="requestOptions"></param>
        /// <returns></returns>
        public async Task <bool> RemovePermissionAsync(string userId, string permissionId, RequestOptions requestOptions = null)
        {
            try
            {
                await documentClient.DeletePermissionAsync(UriFactory.CreatePermissionUri(_database, userId, permissionId), requestOptions);

                return(true);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine($"Unable to remove permission. {e.Message}");
                return(false);
            }
        }
        static async Task <Permission> GenerateReadPermission(string userId, DocumentClient client, string databaseId, string collectionId)
        {
            Permission readPermission = new Permission();

            string permissionId = "";

            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
            Uri userUri       = UriFactory.CreateUserUri(databaseId, userId);

            permissionId = $"{userId}-read-{collectionId}";

            try
            {
                // the permission ID's format: {userID}-{documentID}
                Uri permissionUri = UriFactory.CreatePermissionUri(databaseId, userId, permissionId);

                readPermission = await client.ReadPermissionAsync(permissionUri);
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    // The permission was not found - either the user (and permission) doesn't exist or permission doesn't exist
                    await CreateUserIfNotExistAsync(userId, client, databaseId);

                    var newPermission = new Permission
                    {
                        PermissionMode = PermissionMode.Read,
                        Id             = permissionId,
                        ResourceLink   = collectionUri.ToString()
                    };

                    readPermission = await client.CreatePermissionAsync(userUri, newPermission);
                }
                else
                {
                    throw ex;
                }
            }

            return(readPermission);
        }
Esempio n. 12
0
        /// <summary>
        /// Gets the new permission.
        /// </summary>
        /// <returns>The new permission.</returns>
        /// <param name="userId">User identifier.</param>
        private async Task <PermissionToken> GetNewPermission(string userId)
        {
            Permission permission = null;

            try
            {
                Uri url = UriFactory.CreatePermissionUri(databaseId, userId, permissionId);
                permission = await Client.ReadPermissionAsync(UriFactory.CreatePermissionUri(databaseId, userId, permissionId));
            }
            catch (DocumentClientException e)
            {
                if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    DocumentCollection collection = await Client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId));

                    Permission p = new Permission
                    {
                        PermissionMode       = PermissionMode.All,
                        ResourceLink         = collection.SelfLink,
                        ResourcePartitionKey = new PartitionKey(userId),
                        Id = permissionId // Needs to be unique for a given user
                    };
                    await CreateUserIfNotExistsAsync(userId);

                    permission = await Client.CreatePermissionAsync(UriFactory.CreateUserUri(databaseId, userId), p);
                }
                else
                {
                    throw e;
                }
            }
            var expires = Convert.ToInt32(DateTime.UtcNow.Subtract(BeginningOfTime).TotalSeconds) + 3600; // expires in 1h

            return(new PermissionToken()
            {
                Token = permission.Token,
                Expires = expires,
                UserId = userId
            });
        }
        static async Task <Permission> GetPartitionPermission(string userId, DocumentClient client, string databaseId, string collectionId)
        {
            string     permissionId        = "";
            Permission partitionPermission = new Permission();

            permissionId = $"{userId}-partition-info-{collectionId}";

            Uri permissionUri = UriFactory.CreatePermissionUri(databaseId, userId, permissionId);
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);

            try
            {
                partitionPermission = await client.ReadPermissionAsync(permissionUri);
            }
            catch (DocumentClientException ex)
            {
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    await CreateUserIfNotExistAsync(userId, client, databaseId);

                    var newPermission = new Permission
                    {
                        PermissionMode = PermissionMode.All,
                        Id             = permissionId,
                        ResourceLink   = collectionUri.ToString()
                    };

                    newPermission.ResourcePartitionKey = new PartitionKey($"user-{userId}");

                    var userUri = UriFactory.CreateUserUri(dbName, userId);
                    partitionPermission = await client.CreatePermissionAsync(userUri, newPermission);
                }
            }

            return(partitionPermission);
        }
        static async Task <Permission> CreateNewPermission(this DocumentClient client, string databaseId, string resourceLink, User user, string permissionId, PermissionMode permissionMode, int durationInSeconds, TraceWriter log)
        {
            log?.Info($" ... creating new permission ({permissionId}) for resource at ({resourceLink})");

            var newPermission = new Permission {
                Id = permissionId, PermissionMode = permissionMode
            };

            if (!string.IsNullOrEmpty(resourceLink))
            {
                newPermission.ResourceLink = resourceLink;
            }

            try
            {
                var permissionResponse = await client.CreatePermissionAsync(user.SelfLink, newPermission, PermissionRequestOptions(durationInSeconds));

                var permission = permissionResponse?.Resource;

                if (permission != null)
                {
                    log?.Info($" ... created new permission ({permission.Id})");
                }

                return(permission);
            }
            catch (DocumentClientException dcx)
            {
                dcx.Print(log);

                switch (dcx.StatusCode)
                {
                case HttpStatusCode.Conflict:

                    // check for an existing permission with a different permissionMode
                    var oldPermissionId = permissionId.Replace(permissionMode.ToString().ToUpper(), permissionMode == PermissionMode.All ? PermissionMode.Read.ToString().ToUpper() : PermissionMode.All.ToString().ToUpper());

                    log?.Info($" ... deleting old permission ({oldPermissionId})");

                    await client.DeletePermissionAsync(UriFactory.CreatePermissionUri(databaseId, user.Id, oldPermissionId));

                    log?.Info($" ... creating new permission ({permissionId}) for resource at ({resourceLink})");

                    var permissionResponse = await client.CreatePermissionAsync(user.SelfLink, newPermission, PermissionRequestOptions(durationInSeconds));

                    var permission = permissionResponse?.Resource;

                    if (permission != null)
                    {
                        log?.Info($" ... created new permission ({permission.Id})");
                    }

                    return(permission);

                default: throw;
                }
            }
            catch (Exception ex)
            {
                log?.Error($"Error creating new Permission with Id: {permissionId}  for resource at: {resourceLink}", ex);
                throw;
            }
        }
        public static async Task <Permission> GetOrCreatePermission(this DocumentClient client, string databaseId, string collectionId, string resourceLink, string userId, PermissionMode permissionMode, int durationInSeconds, TraceWriter log)
        {
            var permissionId = string.Empty;

            try
            {
                Database           database           = null;
                DocumentCollection documentCollection = null;

                if (!string.IsNullOrEmpty(collectionId))
                {
                    await client.EnsureCollection(databaseId, collectionId, log);

                    log?.Info($" ... getting collection ({collectionId}) in database ({databaseId})");

                    var collectionResponse = await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId));

                    documentCollection = collectionResponse?.Resource ?? throw new Exception($"Could not find Document Collection in Database {databaseId} with CollectionId: {collectionId}");
                }
                else if (!string.IsNullOrEmpty(databaseId))
                {
                    await client.EnsureDatabase(databaseId, log);

                    log?.Info($" ... collectionId == null, getting database ({databaseId})");

                    var databaseResponse = await client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(databaseId));

                    database = databaseResponse?.Resource ?? throw new Exception($"Could not find Database {databaseId}");
                }
                else
                {
                    throw new Exception($"databaseId and collectionId must be provided");
                }

                var link = resourceLink ?? documentCollection?.SelfLink; //?? throw new Exception($"Could not get selfLink for Document Collection in Database {databaseId} with CollectionId: {collectionId}");

                var userTup = await client.GetOrCreateUser(databaseId, userId, log);

                var user = userTup.user;

                Permission permission;

                permissionId = GetUserPermissionId(databaseId, collectionId, user.Id, permissionMode);

                // if the user was newly created, go ahead and create the permission
                if (userTup.created && !string.IsNullOrEmpty(user?.Id))
                {
                    permission = await client.CreateNewPermission(databaseId, link, user, permissionId, permissionMode, durationInSeconds, log);
                }
                else // else look for an existing permission with the id
                {
                    var permissionUri = UriFactory.CreatePermissionUri(databaseId, user.Id, permissionId);

                    try
                    {
                        log?.Info($" ... getting permission ({permissionId}) at uri: {permissionUri}");

                        var permissionResponse = await client.ReadPermissionAsync(permissionUri, PermissionRequestOptions(durationInSeconds));

                        permission = permissionResponse?.Resource;

                        if (permission != null)
                        {
                            log?.Info($" ... found existing permission ({permission.Id})");
                        }
                    }
                    catch (DocumentClientException dcx)
                    {
                        dcx.Print(log);

                        switch (dcx.StatusCode)
                        {
                        case HttpStatusCode.NotFound:

                            log?.Info($" ... could not find permission ({permissionId}) at uri: {permissionUri} - creating...");

                            permission = await client.CreateNewPermission(databaseId, link, user, permissionId, permissionMode, durationInSeconds, log);

                            break;

                        default: throw;
                        }
                    }
                }

                return(permission);
            }
            catch (Exception ex)
            {
                var resourceComponent = string.IsNullOrEmpty(resourceLink) ? "" : $" Resource: {resourceLink} ";

                log?.Error($"Error creating new new {permissionMode.ToString().ToUpper()} Permission [Database: {databaseId} Collection: {collectionId}{resourceComponent} User: {userId}  Permission: {permissionId}", ex);
                throw;
            }
        }
        static async Task <List <Permission> > GetReadPermission(string userId, DocumentClient client, string databaseId, string collectionId)
        {
            List <Permission> movieReviewPermissions = new List <Permission>();
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, collectionId);
            Uri userUri       = UriFactory.CreateUserUri(databaseId, userId);

            IDocumentQuery <MovieReview> query = null;

            // Get the public or public + premium docs (depending on the user we're working with)
            if (userId == publicUserId)
            {
                query = client.CreateDocumentQuery <MovieReview>(collectionUri).Where(mv => mv.IsPremium == false).AsDocumentQuery();
            }
            else
            {
                query = client.CreateDocumentQuery <MovieReview>(collectionUri).AsDocumentQuery();
            }

            // Now loop through the results and create individual permissions for them
            while (query.HasMoreResults)
            {
                foreach (var movieReview in await query.ExecuteNextAsync <MovieReview>())
                {
                    Permission individualPermission = new Permission();
                    string     permissionId         = $"{userId}-{movieReview.Id}";

                    try
                    {
                        // the permission ID's format: {userID}-{documentID}
                        Uri permissionUri = UriFactory.CreatePermissionUri(databaseId, userId, permissionId);

                        individualPermission = await client.ReadPermissionAsync(permissionUri);

                        movieReviewPermissions.Add(individualPermission);
                    }
                    catch (DocumentClientException ex)
                    {
                        if (ex.StatusCode == HttpStatusCode.NotFound)
                        {
                            // The permission was not found - either the user (and permission) doesn't exist or permission doesn't exist
                            await CreateUserIfNotExistAsync(userId, client, databaseId);

                            var newPermission = new Permission
                            {
                                PermissionMode = PermissionMode.Read,
                                Id             = permissionId,
                                ResourceLink   = UriFactory.CreateDocumentUri(databaseId, collectionId, movieReview.Id).ToString()
                            };

                            individualPermission = await client.CreatePermissionAsync(userUri, newPermission);

                            movieReviewPermissions.Add(individualPermission);
                        }
                        else
                        {
                            throw ex;
                        }
                    }
                }
            }

            return(movieReviewPermissions);
        }
Esempio n. 17
0
        /// <summary>
        /// Get a permission for a user.
        /// <para/>Note: Should only be called from a mid-tier service.
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="permissionId"></param>
        /// <returns>A CosmosDB <see cref="Permission"/></returns>
        public async Task <Permission> GetPermissionAsync(User user, string permissionId, RequestOptions requestOptions = null)
        {
            var feed = await documentClient.ReadPermissionFeedAsync(user.PermissionsLink);

            return(await documentClient.ReadPermissionAsync(UriFactory.CreatePermissionUri(_database, user.Id, permissionId), requestOptions));
        }