public async Task <string> Create( string ownerId, string contextResourceId, TodoCreateData data, Permission callerRights, IDictionary <RightType, Permission> callerCollectionRights) { var todoId = await Create(data); // create a security hole, if the user isn't injected then make the creator the parent resource // which in this case is a user. // KLUDGE : take out. This is only here because of seed data await _userRightStore.CreateRights( ownerId, todoId, RightType.Todo.MakeCreateRights(callerRights, callerCollectionRights), new InheritForm { Type = RightType.UserTodoCollection, ResourceId = contextResourceId, InheritedTypes = new List <RightType> { RightType.Todo, RightType.TodoCommentCollection, RightType.TodoTagCollection } }); return(todoId); }
private async Task <string> Create(TodoCreateData data) { var todo = new Todo { // lists have the Id == Parent // items have separate Id and Parent ids Id = _idGenerator.New(), Parent = data.Parent .ThrowConfigurationErrorsExceptionIfNullOrWhiteSpace("Parent cannot be empty"), Type = data.Type, Name = data.Name, State = data.State, Due = data.Due, CreatedBy = _creatorId, CreatedAt = DateTime.UtcNow, // TODO: validation/cross checking of tag references Tags = data.Tags }; await _context.SaveAsync(todo); Log.DebugFormat("New todo {0} for user {1} by user {1}", todo.Id, _creatorId); return(todo.Id); }
/// <summary> /// Creates a tenant, user on the tenant and some todos with tags /// </summary> public static async Task SeedData(this IServiceProvider services, ILogger log) { /** * Get registered services. */ var context = services.GetRequiredService <IDynamoDBContext>(); var idGenerator = services.GetRequiredService <IIdGenerator>(); var userRightsStore = services.GetRequiredService <IUserRightStore>(); var configuration = services.GetRequiredService <IConfiguration>(); /** * Setup the provisioning user */ var provisioningUser = new User { Id = TrustDefaults.ProvisioningId }; /** * Hand make up these because we want to inject the user with the provisioning user */ var tenantStore = new TenantStore( provisioningUser, context, idGenerator, userRightsStore, services.GetRequiredService <ILogger <TenantStore> >()); var userStore = new UserStore( provisioningUser, context, idGenerator, userRightsStore, services.GetRequiredService <ILogger <UserStore> >()); var tagStore = new TagStore( provisioningUser, context, idGenerator, userRightsStore, services.GetRequiredService <ILogger <TagStore> >()); var todoStore = new TodoStore( provisioningUser, context, idGenerator, userRightsStore, tagStore, tenantStore, services.GetRequiredService <ILogger <TodoStore> >()); // ensure the database is up and tables are created await services.GetRequiredService <IAmazonDynamoDB>() .WaitForAllTables(log); log.Info("[Seed] create sample data"); ////////////////////////// // Authentication // ============== // // A precreated user (in third-party system) [or decoded JWT through https://jwt.io // grab it from the Authorization header in a request] var knownAuth0Id = configuration.GetSection("TestSeedUser").Value; log.DebugFormat("[Seed] found seed user '{0}'", knownAuth0Id); var rootUser = (await userStore.GetByExternalId(TrustDefaults.KnownRootIdentifier)) .ThrowConfigurationErrorsExceptionIfNull(() => "Root user has not been configured"); ////////////////////////// // Seed a user // ============= // // Assume a known Auth0 (test) user, register a user and then link to tenant // var userData = new UserCreateData { Email = "*****@*****.**", Name = "test", ExternalId = knownAuth0Id }; // create seeed data if the user doesn't exist if ((await userStore.GetByExternalId(userData.ExternalId)).IsNull()) { log.Info($"[Seed] user {userData.Email}"); var userId = await userStore.Create( rootUser.Id, TrustDefaults.KnownHomeResourceId, userData, Permission.FullControl | Permission.Owner, CallerCollectionRights.User); ////////////////////////// // Seed a tenant // ============= // var tenantCreateData = new TenantCreateData { Code = "rewire.semanticlink.io", Name = "Rewire", Description = "A sample tenant (company/organisation)" }; log.Info($"[Seed] tenant '{tenantCreateData.Code}'"); var tenantId = await tenantStore.Create( rootUser.Id, TrustDefaults.KnownHomeResourceId, tenantCreateData, Permission.FullControl | Permission.Owner, CallerCollectionRights.Tenant); ////////////////////////// // Add user to tenant // ================== // if (!await tenantStore.IsRegisteredOnTenant(tenantId, userId)) { await tenantStore.IncludeUser( tenantId, userId, Permission.Get | Permission.Owner, CallerCollectionRights.Tenant); } log.Info($"[Seed] registered user '{userData.Email}' against tenant '{tenantCreateData.Code}'"); ////////////////////////// // Seed global tags // ============= // // create some global tags // var tagIds = (await Task.WhenAll( new[] { "Work", "Personal", "Grocery List" } .Select(tag => tagStore.Create( userId, TrustDefaults.KnownHomeResourceId, new TagCreateData { Name = tag }, Permission.Get, CallerCollectionRights.Tag) ))) .Where(result => result != null) .ToList(); log.InfoFormat("[Seed] tags: [{0}]", tagIds.ToCsvString(tagId => tagId)); ///////////////////////////////////// // Seed a named todo list // ====================== // var todoCreateData = new TodoCreateData { Parent = tenantId, Name = "Shopping Todo List", Type = TodoType.List }; var todoListId = await todoStore.Create( userId, tenantId, todoCreateData, Permission.FullControl | Permission.Owner, CallerCollectionRights.Todo); log.InfoFormat("[Seed] todo list [{0}]", todoListId); ////////////////////////// // Seed some todos // =============== // var createTodoDatas = new List <TodoCreateData> { new TodoCreateData { Name = "One Todo", Parent = todoListId, Type = TodoType.Item }, new TodoCreateData { Name = "Two Todo (tag)", Tags = new List <string> { tagIds.First() }, State = TodoState.Complete, Parent = todoListId, Type = TodoType.Item }, new TodoCreateData { Name = "Three Todo (tagged)", Tags = tagIds, Parent = todoListId, Type = TodoType.Item } }; var ids = await Task.WhenAll(createTodoDatas .Select(data => todoStore.Create( userId, userId, data, Permission.FullControl | Permission.Owner, CallerCollectionRights.Todo))); log.InfoFormat("[Seed] todos: [{0}]", ids.ToCsvString(id => id)); } else { log.Debug("[Seed] test data already setup"); } }
public async Task LoadUserRight( Permission explicitRights, Permission callerRights, Permission requiredPermission, bool allow) { // Setup // - user // - todo collection context ( // - todo (that we want to created) Register(services => { services.AddTransient(ctx => new User { Id = UserId }); }); var userRightStore = Get <IUserRightStore>(); var todoStore = Get <ITodoStore>(); var contextResourceId = NewId(); var createData = new TodoCreateData { Name = "Test", Parent = NewId() }; ///////////////////////////////////////////////////////////// // Do the creation of a todo with the rights we want // var todoId = await todoStore.Create( UserId, contextResourceId, createData, explicitRights, new Dictionary <RightType, Permission> { { RightType.UserTodoCollection, callerRights } }); // Results // - find number of user rights and inherited rights // - then, would the user be granted access? var userRights = await Db.ScanAsync <UserRight>(new List <ScanCondition> { new ScanCondition(nameof(UserRight.UserId), ScanOperator.Equal, UserId) }) .GetRemainingAsync(); var userInheritRights = await Db.ScanAsync <UserInheritRight>(new List <ScanCondition> { new ScanCondition(nameof(UserInheritRight.UserId), ScanOperator.Equal, UserId) }) .GetRemainingAsync(); Assert.Equal(2, userRights.Count); Assert.Empty(userInheritRights); // Access? var resourceRights = await userRightStore.Get(UserId, todoId, RightType.Todo); Assert.Equal(allow, resourceRights.hasRights(requiredPermission)); // Clean up await Task.WhenAll(userRights.Select(right => Db.DeleteAsync <UserRight>(right.Id))); await Task.WhenAll(userInheritRights.Select(right => Db.DeleteAsync <UserInheritRight>(right.Id))); await Db.DeleteAsync <Todo>(todoId); }