Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        /// <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);
        }