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); }
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()); }
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); }
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}"); }
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); }
/// <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); }
/// <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); }
/// <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)); }