Exemplo n.º 1
0
        public void TestAllRightsWorks()
        {
            var allByondRights       = ByondRights.CancelInstall | ByondRights.InstallOfficialOrChangeActiveVersion | ByondRights.ListInstalled | ByondRights.ReadActive | ByondRights.InstallCustomVersion;
            var automaticByondRights = RightsHelper.AllRights <ByondRights>();

            Assert.AreEqual(allByondRights, automaticByondRights);
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public async Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken)
        {
            var admin = await GetAdminUser(databaseContext, cancellationToken).ConfigureAwait(false);

            if (admin != null)
            {
                // Fix the issue with ulong enums
                // https://github.com/tgstation/tgstation-server/commit/db341d43b3dab74fe3681f5172ca9bfeaafa6b6d#diff-09f06ec4584665cf89bb77b97f5ccfb9R36-R39
                // https://github.com/JamesNK/Newtonsoft.Json/issues/2301
                admin.AdministrationRights  &= RightsHelper.AllRights <AdministrationRights>();
                admin.InstanceManagerRights &= RightsHelper.AllRights <InstanceManagerRights>();
            }

            if (platformIdentifier.IsWindows)
            {
                // normalize backslashes to forward slashes
                var allInstances = await databaseContext
                                   .Instances
                                   .AsQueryable()
                                   .ToListAsync(cancellationToken)
                                   .ConfigureAwait(false);

                foreach (var instance in allInstances)
                {
                    instance.Path = instance.Path.Replace('\\', '/');
                }
            }

            await databaseContext.Save(cancellationToken).ConfigureAwait(false);
        }
Exemplo n.º 3
0
        /// <inheritdoc />
        public async Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken)
        {
            var admin = await GetAdminUser(databaseContext, cancellationToken).ConfigureAwait(false);

            if (admin != null)
            {
                // Fix the issue with ulong enums
                // https://github.com/tgstation/tgstation-server/commit/db341d43b3dab74fe3681f5172ca9bfeaafa6b6d#diff-09f06ec4584665cf89bb77b97f5ccfb9R36-R39
                // https://github.com/JamesNK/Newtonsoft.Json/issues/2301
                admin.AdministrationRights  = admin.AdministrationRights & RightsHelper.AllRights <AdministrationRights>();
                admin.InstanceManagerRights = admin.InstanceManagerRights & RightsHelper.AllRights <InstanceManagerRights>();
            }

            await databaseContext.Save(cancellationToken).ConfigureAwait(false);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Add a default admin <see cref="User"/> to a given <paramref name="databaseContext"/>
        /// </summary>
        /// <param name="databaseContext">The <see cref="IDatabaseContext"/> to add an admin <see cref="User"/> to</param>
        void SeedAdminUser(IDatabaseContext databaseContext)
        {
            var admin = new User
            {
                AdministrationRights  = RightsHelper.AllRights <AdministrationRights>(),
                CreatedAt             = DateTimeOffset.Now,
                InstanceManagerRights = RightsHelper.AllRights <InstanceManagerRights>(),
                Name          = Api.Models.User.AdminName,
                CanonicalName = User.CanonicalizeName(Api.Models.User.AdminName),
                Enabled       = true,
            };

            cryptographySuite.SetUserPassword(admin, Api.Models.User.DefaultAdminPassword, true);
            databaseContext.Users.Add(admin);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Add a default admin <see cref="User"/> to a given <paramref name="databaseContext"/>
        /// </summary>
        /// <param name="databaseContext">The <see cref="IDatabaseContext"/> to add an admin <see cref="User"/> to</param>
        /// <returns>The created admin <see cref="User"/>.</returns>
        User SeedAdminUser(IDatabaseContext databaseContext)
        {
            var admin = new User
            {
                PermissionSet = new PermissionSet
                {
                    AdministrationRights  = RightsHelper.AllRights <AdministrationRights>(),
                    InstanceManagerRights = RightsHelper.AllRights <InstanceManagerRights>(),
                },
                CreatedAt     = DateTimeOffset.UtcNow,
                Name          = DefaultCredentials.AdminUserName,
                CanonicalName = User.CanonicalizeName(DefaultCredentials.AdminUserName),
                Enabled       = true,
            };

            cryptographySuite.SetUserPassword(admin, DefaultCredentials.DefaultAdminUserPassword, true);
            databaseContext.Users.Add(admin);
            return(admin);
        }
Exemplo n.º 6
0
 Models.InstanceUser InstanceAdminUser(Models.InstanceUser userToModify)
 {
     if (userToModify == null)
     {
         userToModify = new Models.InstanceUser()
         {
             UserId = AuthenticationContext.User.Id.Value
         }
     }
     ;
     userToModify.ByondRights         = RightsHelper.AllRights <ByondRights>();
     userToModify.ChatBotRights       = RightsHelper.AllRights <ChatBotRights>();
     userToModify.ConfigurationRights = RightsHelper.AllRights <ConfigurationRights>();
     userToModify.DreamDaemonRights   = RightsHelper.AllRights <DreamDaemonRights>();
     userToModify.DreamMakerRights    = RightsHelper.AllRights <DreamMakerRights>();
     userToModify.RepositoryRights    = RightsHelper.AllRights <RepositoryRights>();
     userToModify.InstanceUserRights  = RightsHelper.AllRights <InstanceUserRights>();
     return(userToModify);
 }
Exemplo n.º 7
0
 /// <summary>
 /// Generate an <see cref="InstancePermissionSet"/> with full rights.
 /// </summary>
 /// <param name="permissionSetToModify">An optional existing <see cref="InstancePermissionSet"/> to update.</param>
 /// <returns><paramref name="permissionSetToModify"/> or a new <see cref="InstancePermissionSet"/> with full rights.</returns>
 InstancePermissionSet InstanceAdminPermissionSet(InstancePermissionSet permissionSetToModify)
 {
     if (permissionSetToModify == null)
     {
         permissionSetToModify = new InstancePermissionSet()
         {
             PermissionSetId = AuthenticationContext.PermissionSet.Id.Value
         }
     }
     ;
     permissionSetToModify.ByondRights                 = RightsHelper.AllRights <ByondRights>();
     permissionSetToModify.ChatBotRights               = RightsHelper.AllRights <ChatBotRights>();
     permissionSetToModify.ConfigurationRights         = RightsHelper.AllRights <ConfigurationRights>();
     permissionSetToModify.DreamDaemonRights           = RightsHelper.AllRights <DreamDaemonRights>();
     permissionSetToModify.DreamMakerRights            = RightsHelper.AllRights <DreamMakerRights>();
     permissionSetToModify.RepositoryRights            = RightsHelper.AllRights <RepositoryRights>();
     permissionSetToModify.InstancePermissionSetRights = RightsHelper.AllRights <InstancePermissionSetRights>();
     return(permissionSetToModify);
 }
Exemplo n.º 8
0
        /// <summary>
        /// Correct invalid database data caused by previous versions (NOT user fuckery).
        /// </summary>
        /// <param name="databaseContext">The <see cref="IDatabaseContext"/> to sanitize.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
        /// <returns>A <see cref="Task"/> representing the running operation.</returns>
        async Task SanitizeDatabase(IDatabaseContext databaseContext, CancellationToken cancellationToken)
        {
            var admin = await GetAdminUser(databaseContext, cancellationToken).ConfigureAwait(false);

            if (admin != null)
            {
                if (admin.PermissionSet != null)
                {
                    // Fix the issue with ulong enums
                    // https://github.com/tgstation/tgstation-server/commit/db341d43b3dab74fe3681f5172ca9bfeaafa6b6d#diff-09f06ec4584665cf89bb77b97f5ccfb9R36-R39
                    // https://github.com/JamesNK/Newtonsoft.Json/issues/2301
                    admin.PermissionSet.AdministrationRights  &= RightsHelper.AllRights <AdministrationRights>();
                    admin.PermissionSet.InstanceManagerRights &= RightsHelper.AllRights <InstanceManagerRights>();
                }

                if (admin.CreatedBy == null)
                {
                    var tgsUser = await databaseContext
                                  .Users
                                  .AsQueryable()
                                  .Where(x => x.CanonicalName == User.CanonicalizeName(User.TgsSystemUserName))
                                  .FirstOrDefaultAsync(cancellationToken)
                                  .ConfigureAwait(false);

                    if (tgsUser != null)
                    {
                        logger.LogError(
                            "A user named TGS (Canonically) exists but isn't marked as the admin's creator. This may be because it was created manually. This user is going to be adapted to use as the starter of system jobs.");
                    }

                    tgsUser         = SeedSystemUser(databaseContext, tgsUser);
                    admin.CreatedBy = tgsUser;
                }
            }

            if (platformIdentifier.IsWindows)
            {
                // normalize backslashes to forward slashes
                var allInstances = await databaseContext
                                   .Instances
                                   .AsQueryable()
                                   .ToListAsync(cancellationToken)
                                   .ConfigureAwait(false);

                foreach (var instance in allInstances)
                {
                    instance.Path = instance.Path.Replace('\\', '/');
                }
            }

            if (generalConfiguration.ByondTopicTimeout != 0)
            {
                var ids = await databaseContext
                          .DreamDaemonSettings
                          .AsQueryable()
                          .Where(x => x.TopicRequestTimeout == 0)
                          .Select(x => x.Id)
                          .ToListAsync(cancellationToken)
                          .ConfigureAwait(false);

                var rowsUpdated = ids.Count;
                foreach (var id in ids)
                {
                    var newDDSettings = new DreamDaemonSettings
                    {
                        Id = id
                    };

                    databaseContext.DreamDaemonSettings.Attach(newDDSettings);
                    newDDSettings.TopicRequestTimeout = generalConfiguration.ByondTopicTimeout;
                }

                if (rowsUpdated > 0)
                {
                    logger.LogInformation(
                        "Updated {0} instances to use database backed BYOND topic timeouts from configuration setting of {1}",
                        rowsUpdated,
                        generalConfiguration.ByondTopicTimeout);
                }
            }

            await databaseContext.Save(cancellationToken).ConfigureAwait(false);
        }
        public async Task RunPostTest(CancellationToken cancellationToken)
        {
            var instances = await instanceManagerClient.List(cancellationToken);

            var firstTest      = instances.Single(x => x.Name == TestInstanceName);
            var instanceClient = instanceManagerClient.CreateClient(firstTest);

            //can regain permissions on instance without instance user
            var ourInstanceUser = await instanceClient.Users.Read(cancellationToken).ConfigureAwait(false);

            await instanceClient.Users.Delete(ourInstanceUser, cancellationToken).ConfigureAwait(false);

            await Assert.ThrowsExceptionAsync <InsufficientPermissionsException>(() => instanceClient.Users.Read(cancellationToken)).ConfigureAwait(false);

            await instanceManagerClient.GrantPermissions(new Api.Models.Instance
            {
                Id = firstTest.Id
            }, cancellationToken).ConfigureAwait(false);

            ourInstanceUser = await instanceClient.Users.Read(cancellationToken).ConfigureAwait(false);

            Assert.AreEqual(RightsHelper.AllRights <DreamDaemonRights>(), ourInstanceUser.DreamDaemonRights.Value);

            //can't detach online instance
            await ApiAssert.ThrowsException <ConflictException>(() => instanceManagerClient.Detach(firstTest, cancellationToken), ErrorCode.InstanceDetachOnline).ConfigureAwait(false);

            firstTest.Online = false;
            firstTest        = await instanceManagerClient.Update(firstTest, cancellationToken).ConfigureAwait(false);

            await instanceManagerClient.Detach(firstTest, cancellationToken).ConfigureAwait(false);

            var attachPath = Path.Combine(firstTest.Path, InstanceController.InstanceAttachFileName);

            Assert.IsTrue(File.Exists(attachPath));

            //can recreate detached instance
            firstTest = await instanceManagerClient.CreateOrAttach(firstTest, cancellationToken).ConfigureAwait(false);

            // Test updating only with SetChatBotLimit works
            var current = await usersClient.Read(cancellationToken);

            var update = new UserUpdate
            {
                Id = current.Id,
                InstanceManagerRights = InstanceManagerRights.SetChatBotLimit
            };
            await usersClient.Update(update, cancellationToken);

            var update2 = new Api.Models.Instance
            {
                Id           = firstTest.Id,
                ChatBotLimit = 77
            };
            var newThing = await instanceManagerClient.Update(update2, cancellationToken);

            update.InstanceManagerRights |= InstanceManagerRights.Delete | InstanceManagerRights.Create | InstanceManagerRights.List;
            await usersClient.Update(update, cancellationToken);

            //but only if the attach file exists
            await instanceManagerClient.Detach(firstTest, cancellationToken).ConfigureAwait(false);

            File.Delete(attachPath);
            await ApiAssert.ThrowsException <ConflictException>(() => instanceManagerClient.CreateOrAttach(firstTest, cancellationToken), ErrorCode.InstanceAtExistingPath).ConfigureAwait(false);
        }
Exemplo n.º 10
0
        async Task BasicTests(CancellationToken cancellationToken)
        {
            var user = await serverClient.Users.Read(cancellationToken).ConfigureAwait(false);

            Assert.IsNotNull(user);
            Assert.AreEqual("Admin", user.Name);
            Assert.IsNull(user.SystemIdentifier);
            Assert.AreEqual(true, user.Enabled);
            Assert.IsNotNull(user.OAuthConnections);
            Assert.IsNotNull(user.PermissionSet);
            Assert.IsNotNull(user.PermissionSet.Id);
            Assert.IsNotNull(user.PermissionSet.InstanceManagerRights);
            Assert.IsNotNull(user.PermissionSet.AdministrationRights);

            var systemUser = user.CreatedBy;

            Assert.IsNotNull(systemUser);
            Assert.AreEqual("TGS", systemUser.Name);

            var users = await serverClient.Users.List(null, cancellationToken);

            Assert.IsTrue(users.Count > 0);
            Assert.IsFalse(users.Any(x => x.Id == systemUser.Id));

            await ApiAssert.ThrowsException <InsufficientPermissionsException>(() => serverClient.Users.GetId(systemUser, cancellationToken), null);

            await ApiAssert.ThrowsException <InsufficientPermissionsException>(() => serverClient.Users.Update(new UserUpdateRequest
            {
                Id = systemUser.Id
            }, cancellationToken), null);

            var sampleOAuthConnections = new List <OAuthConnection>
            {
                new OAuthConnection
                {
                    ExternalUserId = "asdfasdf",
                    Provider       = OAuthProvider.Discord
                }
            };
            await ApiAssert.ThrowsException <ApiConflictException>(() => serverClient.Users.Update(new UserUpdateRequest
            {
                Id = user.Id,
                OAuthConnections = sampleOAuthConnections
            }, cancellationToken), ErrorCode.AdminUserCannotOAuth);

            var testUser = await serverClient.Users.Create(
                new UserCreateRequest
            {
                Name     = $"BasicTestUser",
                Password = "******"
            },
                cancellationToken).ConfigureAwait(false);

            Assert.IsNotNull(testUser.OAuthConnections);
            testUser = await serverClient.Users.Update(
                new UserUpdateRequest
            {
                Id = testUser.Id,
                OAuthConnections = sampleOAuthConnections
            },
                cancellationToken).ConfigureAwait(false);

            Assert.AreEqual(1, testUser.OAuthConnections.Count);
            Assert.AreEqual(sampleOAuthConnections.First().ExternalUserId, testUser.OAuthConnections.First().ExternalUserId);
            Assert.AreEqual(sampleOAuthConnections.First().Provider, testUser.OAuthConnections.First().Provider);


            var group = await serverClient.Groups.Create(
                new UserGroupCreateRequest
            {
                Name = "TestGroup"
            },
                cancellationToken);

            Assert.AreEqual(group.Name, "TestGroup");
            Assert.IsNotNull(group.PermissionSet);
            Assert.IsNotNull(group.PermissionSet.Id);
            Assert.AreEqual(AdministrationRights.None, group.PermissionSet.AdministrationRights);
            Assert.AreEqual(InstanceManagerRights.None, group.PermissionSet.InstanceManagerRights);

            var group2 = await serverClient.Groups.Create(new UserGroupCreateRequest
            {
                Name          = "TestGroup2",
                PermissionSet = new PermissionSet
                {
                    InstanceManagerRights = InstanceManagerRights.List
                }
            }, cancellationToken);

            Assert.AreEqual(AdministrationRights.None, group2.PermissionSet.AdministrationRights);
            Assert.AreEqual(InstanceManagerRights.List, group2.PermissionSet.InstanceManagerRights);

            var groups = await serverClient.Groups.List(null, cancellationToken);

            Assert.AreEqual(2, groups.Count);

            foreach (var igroup in groups)
            {
                Assert.IsNotNull(igroup.Users);
                Assert.IsNotNull(igroup.PermissionSet);
            }

            await serverClient.Groups.Delete(group2, cancellationToken);

            groups = await serverClient.Groups.List(null, cancellationToken);

            Assert.AreEqual(1, groups.Count);

            group = await serverClient.Groups.Update(new UserGroupUpdateRequest
            {
                Id            = groups.First().Id,
                PermissionSet = new PermissionSet
                {
                    InstanceManagerRights = RightsHelper.AllRights <InstanceManagerRights>(),
                    AdministrationRights  = RightsHelper.AllRights <AdministrationRights>(),
                }
            }, cancellationToken);

            Assert.AreEqual(RightsHelper.AllRights <AdministrationRights>(), group.PermissionSet.AdministrationRights);
            Assert.AreEqual(RightsHelper.AllRights <InstanceManagerRights>(), group.PermissionSet.InstanceManagerRights);

            UserUpdateRequest testUserUpdate = new UserCreateRequest
            {
                Name     = "TestUserWithNoPassword",
                Password = String.Empty
            };

            await ApiAssert.ThrowsException <ApiConflictException>(() => serverClient.Users.Create((UserCreateRequest)testUserUpdate, cancellationToken), ErrorCode.UserPasswordLength);

            testUserUpdate.OAuthConnections = new List <OAuthConnection>
            {
                new OAuthConnection
                {
                    ExternalUserId = "asdf",
                    Provider       = OAuthProvider.GitHub
                }
            };

            var testUser2 = await serverClient.Users.Create((UserCreateRequest)testUserUpdate, cancellationToken);

            testUserUpdate = new UserUpdateRequest
            {
                Id            = testUser2.Id,
                PermissionSet = testUser2.PermissionSet,
                Group         = new Api.Models.Internal.UserGroup
                {
                    Id = group.Id
                },
            };
            await ApiAssert.ThrowsException <ApiConflictException>(
                () => serverClient.Users.Update(
                    testUserUpdate,
                    cancellationToken),
                ErrorCode.UserGroupAndPermissionSet);

            testUserUpdate.PermissionSet = null;

            testUser2 = await serverClient.Users.Update(testUserUpdate, cancellationToken);

            Assert.IsNull(testUser2.PermissionSet);
            Assert.IsNotNull(testUser2.Group);
            Assert.AreEqual(group.Id, testUser2.Group.Id);

            group = await serverClient.Groups.GetId(group, cancellationToken);

            Assert.IsNotNull(group.Users);
            Assert.AreEqual(1, group.Users.Count);
            Assert.AreEqual(testUser2.Id, group.Users.First().Id);
            Assert.IsNotNull(group.PermissionSet);
        }