private void PopulateData()
        {
            using (SqlConnection connection = new SqlConnection(this._connString))
            {
                SqlDataReader dataReader = null;

                string selectSql = @"SELECT * FROM dbo.posVwUserRight ORDER BY IdUserRight;";

                SqlCommand command = new SqlCommand(selectSql, connection);

                connection.Open();

                this._urgStore.Clear();

                dataReader = command.ExecuteReader();

                while (dataReader.Read())
                {
                    this._urgStore.Add(new UserRight()
                    {
                        Id     = (string)dataReader["IdUserRight"],
                        Name   = (string)dataReader["Name"],
                        Rights = RightsHelper.ToRights((string)dataReader["Rights"]),
                        Status = (bool)dataReader["Status"]
                    });
                }
            }
        }
        public void TestAllRightsWorks()
        {
            var allByondRights       = ByondRights.CancelInstall | ByondRights.InstallOfficialOrChangeActiveVersion | ByondRights.ListInstalled | ByondRights.ReadActive | ByondRights.InstallCustomVersion;
            var automaticByondRights = RightsHelper.AllRights <ByondRights>();

            Assert.AreEqual(allByondRights, automaticByondRights);
        }
        public void TestAllPowerOfTwo()
        {
            var ulongType = typeof(ulong);

            foreach (var I in Enum.GetValues(typeof(RightsType)).Cast <RightsType>())
            {
                var expectedLog = -1;
                var rightType   = RightsHelper.RightToType(I);
                foreach (var J in Enum.GetValues(rightType))
                {
                    Assert.AreEqual(ulongType, Enum.GetUnderlyingType(rightType));
                    var asUlong = (ulong)J;
                    var isOne   = asUlong == 1;
                    if (!isOne)
                    {
                        Assert.AreEqual(0U, asUlong % 2, String.Format("Enum {0} of {1} is not a power of 2!", Enum.GetName(rightType, asUlong), rightType));
                    }

                    if (expectedLog > -1)
                    {
                        var log = Math.Log(asUlong, 2);
                        if (log != expectedLog)
                        {
                            Assert.Fail(String.Format("Expected Log2({1}) == {0} to come next for {2}, got {3} instead!", expectedLog, Enum.GetName(rightType, asUlong), rightType, log));
                        }
                    }
                    ++expectedLog;
                }
            }
        }
Beispiel #4
0
        /// <inheritdoc />
        public ulong GetRight(RightsType rightsType)
        {
            var isInstance = RightsHelper.IsInstanceRight(rightsType);

            //forces the null user check
            var pullThis = User;

            if (isInstance && InstanceUser == null)
            {
                return(0);
            }
            var rightsEnum = RightsHelper.RightToType(rightsType);
            // use the api versions because they're the ones that contain the actual properties
            var typeToCheck = isInstance ? typeof(InstanceUser) : typeof(User);

            var nullableType       = typeof(Nullable <>);
            var nullableRightsType = nullableType.MakeGenericType(rightsEnum);

            var prop = typeToCheck.GetProperties().Where(x => x.PropertyType == nullableRightsType).First();

            var right = prop.GetMethod.Invoke(isInstance ? (object)InstanceUser : User, Array.Empty <object>());

            if (right == null)
            {
                throw new InvalidOperationException("A user right was null!");
            }
            return((ulong)right);
        }
Beispiel #5
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);
        }
Beispiel #6
0
#pragma warning disable CA1506
        public async Task <IActionResult> Create([FromBody] InstancePermissionSetRequest model, CancellationToken cancellationToken)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var existingPermissionSet = await DatabaseContext
                                        .PermissionSets
                                        .AsQueryable()
                                        .Where(x => x.Id == model.PermissionSetId)
                                        .Select(x => new Models.PermissionSet
            {
                UserId = x.UserId,
            })
                                        .FirstOrDefaultAsync(cancellationToken)
                                        .ConfigureAwait(false);

            if (existingPermissionSet == default)
            {
                return(Gone());
            }

            if (existingPermissionSet.UserId.HasValue)
            {
                var userCanonicalName = await DatabaseContext
                                        .Users
                                        .AsQueryable()
                                        .Where(x => x.Id == existingPermissionSet.UserId.Value)
                                        .Select(x => x.CanonicalName)
                                        .FirstAsync(cancellationToken)
                                        .ConfigureAwait(false);

                if (userCanonicalName == Models.User.CanonicalizeName(Models.User.TgsSystemUserName))
                {
                    return(Forbid());
                }
            }

            var dbUser = new InstancePermissionSet
            {
                ByondRights                 = RightsHelper.Clamp(model.ByondRights ?? ByondRights.None),
                ChatBotRights               = RightsHelper.Clamp(model.ChatBotRights ?? ChatBotRights.None),
                ConfigurationRights         = RightsHelper.Clamp(model.ConfigurationRights ?? ConfigurationRights.None),
                DreamDaemonRights           = RightsHelper.Clamp(model.DreamDaemonRights ?? DreamDaemonRights.None),
                DreamMakerRights            = RightsHelper.Clamp(model.DreamMakerRights ?? DreamMakerRights.None),
                RepositoryRights            = RightsHelper.Clamp(model.RepositoryRights ?? RepositoryRights.None),
                InstancePermissionSetRights = RightsHelper.Clamp(model.InstancePermissionSetRights ?? InstancePermissionSetRights.None),
                PermissionSetId             = model.PermissionSetId,
                InstanceId = Instance.Id.Value,
            };

            DatabaseContext.InstancePermissionSets.Add(dbUser);

            await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);

            return(Created(dbUser.ToApi()));
        }
Beispiel #7
0
        private void RemoveInappropriateRecordsByRight(string schemaName, List <InitialResultItem> initResults)
        {
            List <Guid>  recordIds    = initResults.Select(initResult => initResult.RecordId).Distinct().ToList();
            RightsHelper rightsHelper = GetRightsServiceHelper();

            foreach (Guid recordId in recordIds)
            {
                bool canEdit = rightsHelper.GetCanEditSchemaRecordRight(schemaName, recordId);
                if (!canEdit)
                {
                    initResults.RemoveAll(initResult => initResult.RecordId == recordId);
                }
            }
        }
Beispiel #8
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);
        }
Beispiel #9
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);
        }
Beispiel #10
0
        /// <summary>
        /// Handles entity Inserted event.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">The <see cref="T:Terrasoft.Core.Entities.EntityAfterEventArgs" /> instance containing the
        /// event data.</param>
        public override void OnInserted(object sender, EntityAfterEventArgs e)
        {
            base.OnInserted(sender, e);
            Entity adminUnit = (Entity)sender;

            if (adminUnit.GetTypedColumnValue <Guid>("ContactId") != Guid.Empty &&
                adminUnit.GetTypedColumnValue <bool>("ConnectionType"))
            {
                RightsHelper = RightsHelper ?? new RightsHelper(adminUnit.UserConnection);
                RightsHelper.SetRecordRight(adminUnit.GetTypedColumnValue <Guid>("Id"), "Contact",
                                            adminUnit.GetTypedColumnValue <string>("ContactId"), 0, 2);
                RightsHelper.SetRecordRight(adminUnit.GetTypedColumnValue <Guid>("Id"), "Contact",
                                            adminUnit.GetTypedColumnValue <string>("ContactId"), 1, 2);
            }
        }
        protected virtual void SetCopiedRecordsRights()
        {
            RightsHelper rightHelper = ClassFactory.Get <RightsHelper>(new ConstructorArgument("userConnection",
                                                                                               UserConnection.AppConnection.SystemUserConnection));

            foreach (var entity in InsertQueue)
            {
                var recordRecordId = entity.GetTypedColumnValue <string>("Id");
                rightHelper.SetRecordRight(UserConnection.CurrentUser.Id, "Project", recordRecordId,
                                           (int)EntitySchemaRecordRightOperation.Read, (int)EntitySchemaRecordRightLevel.AllowAndGrant);
                rightHelper.SetRecordRight(UserConnection.CurrentUser.Id, "Project", recordRecordId,
                                           (int)EntitySchemaRecordRightOperation.Edit, (int)EntitySchemaRecordRightLevel.AllowAndGrant);
                rightHelper.SetRecordRight(UserConnection.CurrentUser.Id, "Project", recordRecordId,
                                           (int)EntitySchemaRecordRightOperation.Delete, (int)EntitySchemaRecordRightLevel.AllowAndGrant);
            }
        }
Beispiel #12
0
        /// <summary>
        /// 获取该角色所拥有的菜单按钮权限
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public ActionResult GetRoleMenuButton(int roleId)
        {
            var result = string.Empty;

            var rs = _roleService.GetRoleMenuButton(roleId);

            if (rs.ReturnCode == ReturnCodeType.Success)
            {
                var roleMenuButtons = rs.Content;
                if (roleMenuButtons.HasValue())
                {
                    result = RightsHelper.GetRoleMenuButtonStr(roleMenuButtons, roleId);
                }
            }

            return(Content(result));
        }
Beispiel #13
0
        private void InsertData(UserRight userRight)
        {
            using (SqlConnection connection = new SqlConnection(this._connString))
            {
                string insertIntoSql = @"INSERT INTO dbo.posTbUserRight (IdUserRight, Name, Rights, Status) VALUES (@URGIdUserRight, @URGName, @URGRights, @URGStatus);";

                SqlCommand command = new SqlCommand(insertIntoSql, connection);

                command.Parameters.Add("@URGIdUserRight", SqlDbType.Char).Value = userRight.Id;
                command.Parameters.Add("@URGName", SqlDbType.VarChar).Value     = userRight.Name;
                command.Parameters.Add("@URGRights", SqlDbType.VarChar).Value   = RightsHelper.ToVarchar(userRight.Rights);
                command.Parameters.Add("@URGStatus", SqlDbType.Bit).Value       = userRight.Status;

                connection.Open();

                command.ExecuteNonQuery();
            }
        }
Beispiel #14
0
        private void UpdateData(UserRight userRight)
        {
            using (SqlConnection connection = new SqlConnection(this._connString))
            {
                string updateSql = @"UPDATE dbo.posTbUserRight SET Name = @URGName, Rights = @URGRights, Status = @URGStatus WHERE IdUserRight = @URGIdUserRight;";

                SqlCommand command = new SqlCommand(updateSql, connection);

                command.Parameters.Add("@URGIdUserRight", SqlDbType.Char).Value = userRight.Id;
                command.Parameters.Add("@URGName", SqlDbType.VarChar).Value     = userRight.Name;
                command.Parameters.Add("@URGRights", SqlDbType.VarChar).Value   = RightsHelper.ToVarchar(userRight.Rights);
                command.Parameters.Add("@URGStatus", SqlDbType.Bit).Value       = userRight.Status;

                connection.Open();

                command.ExecuteNonQuery();
            }
        }
Beispiel #15
0
        public async Task <IActionResult> Create([FromBody] Api.Models.InstanceUser model, CancellationToken cancellationToken)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var userCanonicalName = await DatabaseContext
                                    .Users
                                    .AsQueryable()
                                    .Where(x => x.Id == model.UserId)
                                    .Select(x => x.CanonicalName)
                                    .FirstOrDefaultAsync(cancellationToken)
                                    .ConfigureAwait(false);

            if (userCanonicalName == default)
            {
                return(BadRequest(new ErrorMessage(ErrorCode.ModelValidationFailure)));
            }

            if (userCanonicalName == Models.User.CanonicalizeName(Models.User.TgsSystemUserName))
            {
                return(Forbid());
            }

            var dbUser = new Models.InstanceUser
            {
                ByondRights         = RightsHelper.Clamp(model.ByondRights ?? ByondRights.None),
                ChatBotRights       = RightsHelper.Clamp(model.ChatBotRights ?? ChatBotRights.None),
                ConfigurationRights = RightsHelper.Clamp(model.ConfigurationRights ?? ConfigurationRights.None),
                DreamDaemonRights   = RightsHelper.Clamp(model.DreamDaemonRights ?? DreamDaemonRights.None),
                DreamMakerRights    = RightsHelper.Clamp(model.DreamMakerRights ?? DreamMakerRights.None),
                RepositoryRights    = RightsHelper.Clamp(model.RepositoryRights ?? RepositoryRights.None),
                InstanceUserRights  = RightsHelper.Clamp(model.InstanceUserRights ?? InstanceUserRights.None),
                UserId     = model.UserId,
                InstanceId = Instance.Id
            };

            DatabaseContext.InstanceUsers.Add(dbUser);

            await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);

            return(Created(dbUser.ToApi()));
        }
Beispiel #16
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);
        }
Beispiel #17
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);
 }
Beispiel #18
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);
 }
Beispiel #19
0
        /// <summary>
        /// 我的权限
        /// </summary>
        /// <returns></returns>
        public ActionResult GetMyAuthority()
        {
            //获取当前用户所拥有的所有角色
            //获取角色关联的角色菜单按钮信息
            var result = string.Empty;

            var rs = _accountService.GetMyAuthority(base.loginInfo.Id);

            if (rs.ReturnCode == ReturnCodeType.Success)
            {
                var roleMenuButtons = rs.Content;
                if (roleMenuButtons.HasValue())
                {
                    result = RightsHelper.GetRoleMenuButtonStr(roleMenuButtons);
                }
            }

            return(Content(result));
        }
Beispiel #20
0
#pragma warning disable CA1506 // TODO: Decomplexify
        public async Task <IActionResult> Update([FromBody] InstancePermissionSetRequest model, CancellationToken cancellationToken)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var originalPermissionSet = await DatabaseContext
                                        .Instances
                                        .AsQueryable()
                                        .Where(x => x.Id == Instance.Id)
                                        .SelectMany(x => x.InstancePermissionSets)
                                        .Where(x => x.PermissionSetId == model.PermissionSetId)
                                        .FirstOrDefaultAsync(cancellationToken)
                                        .ConfigureAwait(false);

            if (originalPermissionSet == null)
            {
                return(Gone());
            }

            originalPermissionSet.ByondRights                 = RightsHelper.Clamp(model.ByondRights ?? originalPermissionSet.ByondRights.Value);
            originalPermissionSet.RepositoryRights            = RightsHelper.Clamp(model.RepositoryRights ?? originalPermissionSet.RepositoryRights.Value);
            originalPermissionSet.InstancePermissionSetRights = RightsHelper.Clamp(model.InstancePermissionSetRights ?? originalPermissionSet.InstancePermissionSetRights.Value);
            originalPermissionSet.ChatBotRights               = RightsHelper.Clamp(model.ChatBotRights ?? originalPermissionSet.ChatBotRights.Value);
            originalPermissionSet.ConfigurationRights         = RightsHelper.Clamp(model.ConfigurationRights ?? originalPermissionSet.ConfigurationRights.Value);
            originalPermissionSet.DreamDaemonRights           = RightsHelper.Clamp(model.DreamDaemonRights ?? originalPermissionSet.DreamDaemonRights.Value);
            originalPermissionSet.DreamMakerRights            = RightsHelper.Clamp(model.DreamMakerRights ?? originalPermissionSet.DreamMakerRights.Value);

            await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);

            var showFullPermissionSet = originalPermissionSet.PermissionSetId == AuthenticationContext.PermissionSet.Id.Value ||
                                        (AuthenticationContext.GetRight(RightsType.InstancePermissionSet) & (ulong)InstancePermissionSetRights.Read) != 0;

            return(Json(
                       showFullPermissionSet
                                        ? originalPermissionSet.ToApi()
                                        : new InstancePermissionSetResponse
            {
                PermissionSetId = originalPermissionSet.PermissionSetId,
            }));
        }
Beispiel #21
0
        /// <summary>
        /// 获取该角色所拥有的菜单按钮权限
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public ActionResult GetRoleMenuButton(int roleId)
        {
            var result = string.Empty;

            using (var factory = new ChannelFactory <IRightsRoleService>("*"))
            {
                var client = factory.CreateChannel();
                var rs     = client.GetRoleMenuButton(roleId);
                if (rs.ReturnCode == ReturnCodeType.Success)
                {
                    var roleMenuButtons = rs.Content;
                    if (roleMenuButtons.HasValue())
                    {
                        result = RightsHelper.GetRoleMenuButtonStr(roleMenuButtons, roleId);
                    }
                }
            }

            return(Content(result));
        }
Beispiel #22
0
        /// <summary>
        /// 我的权限
        /// </summary>
        /// <returns></returns>
        public ActionResult GetMyAuthority()
        {
            //获取当前用户所拥有的所有角色
            //获取角色关联的角色菜单按钮信息
            var result = string.Empty;

            using (var factory = new ChannelFactory <IRightsAccountService>("*"))
            {
                var client = factory.CreateChannel();
                var rs     = client.GetMyAuthority(base.loginInfo.Id);
                if (rs.ReturnCode == ReturnCodeType.Success)
                {
                    var roleMenuButtons = rs.Content;
                    if (roleMenuButtons.HasValue())
                    {
                        result = RightsHelper.GetRoleMenuButtonStr(roleMenuButtons);
                    }
                }
            }

            return(Content(result));
        }
                #pragma warning disable CA1506 // TODO: Decomplexify
        public async Task <IActionResult> Update([FromBody] Api.Models.InstanceUser model, CancellationToken cancellationToken)
        {
            var earlyOut = StandardModelChecks(model);

            if (earlyOut != null)
            {
                return(earlyOut);
            }

            var originalUser = await DatabaseContext
                               .Instances
                               .AsQueryable()
                               .Where(x => x.Id == Instance.Id)
                               .SelectMany(x => x.InstanceUsers)
                               .Where(x => x.UserId == model.UserId)
                               .FirstOrDefaultAsync(cancellationToken)
                               .ConfigureAwait(false);

            if (originalUser == null)
            {
                return(StatusCode((int)HttpStatusCode.Gone));
            }

            originalUser.ByondRights         = RightsHelper.Clamp(model.ByondRights ?? originalUser.ByondRights.Value);
            originalUser.RepositoryRights    = RightsHelper.Clamp(model.RepositoryRights ?? originalUser.RepositoryRights.Value);
            originalUser.InstanceUserRights  = RightsHelper.Clamp(model.InstanceUserRights ?? originalUser.InstanceUserRights.Value);
            originalUser.ChatBotRights       = RightsHelper.Clamp(model.ChatBotRights ?? originalUser.ChatBotRights.Value);
            originalUser.ConfigurationRights = RightsHelper.Clamp(model.ConfigurationRights ?? originalUser.ConfigurationRights.Value);
            originalUser.DreamDaemonRights   = RightsHelper.Clamp(model.DreamDaemonRights ?? originalUser.DreamDaemonRights.Value);
            originalUser.DreamMakerRights    = RightsHelper.Clamp(model.DreamMakerRights ?? originalUser.DreamMakerRights.Value);

            await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);

            return(Json(originalUser.UserId == AuthenticationContext.User.Id || (AuthenticationContext.GetRight(RightsType.InstanceUser) & (ulong)InstanceUserRights.ReadUsers) != 0 ? originalUser.ToApi() : new Api.Models.InstanceUser
            {
                UserId = originalUser.UserId
            }));
        }
        public async Task <IActionResult> Create([FromBody] Api.Models.InstanceUser model, CancellationToken cancellationToken)
        {
            // Don't check the result as how can a new user have an ID
            StandardModelChecks(model);

            var dbUser = new Models.InstanceUser
            {
                ByondRights         = RightsHelper.Clamp(model.ByondRights ?? ByondRights.None),
                ChatBotRights       = RightsHelper.Clamp(model.ChatBotRights ?? ChatBotRights.None),
                ConfigurationRights = RightsHelper.Clamp(model.ConfigurationRights ?? ConfigurationRights.None),
                DreamDaemonRights   = RightsHelper.Clamp(model.DreamDaemonRights ?? DreamDaemonRights.None),
                DreamMakerRights    = RightsHelper.Clamp(model.DreamMakerRights ?? DreamMakerRights.None),
                RepositoryRights    = RightsHelper.Clamp(model.RepositoryRights ?? RepositoryRights.None),
                InstanceUserRights  = RightsHelper.Clamp(model.InstanceUserRights ?? InstanceUserRights.None),
                UserId     = model.UserId,
                InstanceId = Instance.Id
            };

            DatabaseContext.InstanceUsers.Add(dbUser);

            await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);

            return(StatusCode((int)HttpStatusCode.Created, dbUser.ToApi()));
        }
Beispiel #25
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);
        }
Beispiel #26
0
        public async Task <string> AddRole(AddRoleVm role, Token user)
        {
            if (role == null)
            {
                return(Tip.BadRequest);
            }

            bool isUpdate = role.Tid > 0;

            if (!isUpdate)
            {
                var en = await this.Entity.FirstOrDefaultAsync(r => r.IsActive && r.RoleName.Equals(role.RoleName.Trim()));

                if (en != null)
                {
                    return(Tip.RoleNameIsExists);
                }
            }
            else
            {
                var en = await this.Entity.FirstOrDefaultAsync(r => r.IsActive && !r.Tid.Equals(role.Tid) && r.RoleName.Equals(role.RoleName.Trim()));

                if (en != null)
                {
                    return(Tip.RoleNameIsExists);
                }
            }


            var menuRights = RightsHelper.SumRights(role.Ids.ToList());
            var actionList = role.Actions.GroupBy(r => r.MenuId)
                             .Select(r => new MenuActionSM
            {
                MenuTid    = r.Key,
                ActionList = r.Select(y => new ActionSM
                {
                    ActionId   = y.ActionId,
                    ActionName = y.ActionName
                }).ToList()
            }).ToList();
            var systemRole = new SystemRole
            {
                ActionList    = JsonConvert.SerializeObject(actionList),
                IsActive      = true,
                MenuRights    = menuRights.ToString(),
                RoleName      = role.RoleName,
                Description   = role.RoleDesc,
                CreateUser    = user.Eid,
                CreateRoleTid = user.RoleTid
            };

            if (!isUpdate)
            {
                var saveResult = this.Save(systemRole) > 0;
                if (!saveResult)
                {
                    return(Tip.InserError);
                }
            }
            else
            {
                //更新角色
                var updateResult = this.Entity.Where(r => r.Tid.Equals(role.Tid))
                                   .Set(r => r.DataChangeLastTime, DateTime.Now)
                                   .Set(r => r.RoleName, systemRole.RoleName)
                                   .Set(r => r.Description, systemRole.Description)
                                   .Set(r => r.MenuRights, systemRole.MenuRights)
                                   .Set(r => r.ActionList, systemRole.ActionList)
                                   .Update() > 0;

                if (!updateResult)
                {
                    return(Tip.UpdateError);
                }

                //更新所有角色下的用户菜单权限
                Entitys.SystemUsers.Where(r => r.RoleTid.Equals(role.Tid))
                .Set(r => r.MenuRights, systemRole.MenuRights)
                .Set(r => r.DataChangeLastTime, DateTime.Now)
                .Update();
            }

            return(string.Empty);
        }
        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);
        }
Beispiel #28
0
        /// <summary>
        /// Runs after a <see cref="Token"/> has been validated. Creates the <see cref="IAuthenticationContext"/> for the <see cref="ControllerBase.Request"/>
        /// </summary>
        /// <param name="context">The <see cref="TokenValidatedContext"/> for the operation</param>
        /// <returns>A <see cref="Task"/> representing the running operation</returns>
        public static async Task OnTokenValidated(TokenValidatedContext context)
        {
            var databaseContext = context.HttpContext.RequestServices.GetRequiredService <IDatabaseContext>();
            var authenticationContextFactory = context.HttpContext.RequestServices.GetRequiredService <IAuthenticationContextFactory>();

            var userIdClaim = context.Principal.FindFirst(JwtRegisteredClaimNames.Sub);

            if (userIdClaim == default(Claim))
            {
                throw new InvalidOperationException("Missing required claim!");
            }

            long userId;

            try
            {
                userId = Int64.Parse(userIdClaim.Value, CultureInfo.InvariantCulture);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Failed to parse user ID!", e);
            }

            ApiHeaders apiHeaders;

            try
            {
                apiHeaders = new ApiHeaders(context.HttpContext.Request.GetTypedHeaders());
            }
            catch
            {
                //let OnActionExecutionAsync handle the reponse
                return;
            }

            await authenticationContextFactory.CreateAuthenticationContext(userId, apiHeaders.InstanceId, context.SecurityToken.ValidFrom, context.HttpContext.RequestAborted).ConfigureAwait(false);

            var authenticationContext = authenticationContextFactory.CurrentAuthenticationContext;

            var enumerator = Enum.GetValues(typeof(RightsType));
            var claims     = new List <Claim>();

            foreach (RightsType I in enumerator)
            {
                //if there's no instance user, do a weird thing and add all the instance roles
                //we need it so we can get to OnActionExecutionAsync where we can properly decide between BadRequest and Forbid
                //if user is null that means they got the token with an expired password
                var rightInt  = authenticationContext.User == null || (RightsHelper.IsInstanceRight(I) && authenticationContext.InstanceUser == null) ? ~0U : authenticationContext.GetRight(I);
                var rightEnum = RightsHelper.RightToType(I);
                var right     = (Enum)Enum.ToObject(rightEnum, rightInt);
                foreach (Enum J in Enum.GetValues(rightEnum))
                {
                    if (right.HasFlag(J))
                    {
                        claims.Add(new Claim(ClaimTypes.Role, RightsHelper.RoleName(I, J)));
                    }
                }
            }

            context.Principal.AddIdentity(new ClaimsIdentity(claims));
        }
        /// <inheritdoc />
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            operation.OperationId = $"{context.MethodInfo.DeclaringType.Name}.{context.MethodInfo.Name}";

            var authAttributes = context
                                 .MethodInfo
                                 .DeclaringType
                                 .GetCustomAttributes(true)
                                 .Union(
                context
                .MethodInfo
                .GetCustomAttributes(true))
                                 .OfType <TgsAuthorizeAttribute>();

            if (authAttributes.Any())
            {
                var tokenScheme = new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id   = TokenSecuritySchemeId
                    }
                };

                operation.Security = new List <OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        {
                            tokenScheme,
                            new List <string>()
                        }
                    }
                };

                if (authAttributes.Any(attr => attr.RightsType.HasValue && RightsHelper.IsInstanceRight(attr.RightsType.Value)))
                {
                    operation.Parameters.Add(new OpenApiParameter
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.Parameter,
                            Id   = ApiHeaders.InstanceIdHeader
                        }
                    });
                }
            }
            else
            {
                // HomeController.CreateToken
                var passwordScheme = new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id   = PasswordSecuritySchemeId
                    }
                };

                operation.Security = new List <OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        {
                            passwordScheme,
                            new List <string>()
                        }
                    }
                };
            }
        }
        /// <inheritdoc />
        public async Task InjectClaimsIntoContext(TokenValidatedContext tokenValidatedContext, CancellationToken cancellationToken)
        {
            if (tokenValidatedContext == null)
            {
                throw new ArgumentNullException(nameof(tokenValidatedContext));
            }

            // Find the user id in the token
            var userIdClaim = tokenValidatedContext.Principal.FindFirst(JwtRegisteredClaimNames.Sub);

            if (userIdClaim == default)
            {
                throw new InvalidOperationException("Missing required claim!");
            }

            long userId;

            try
            {
                userId = Int64.Parse(userIdClaim.Value, CultureInfo.InvariantCulture);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Failed to parse user ID!", e);
            }

            ApiHeaders apiHeaders;

            try
            {
                apiHeaders = new ApiHeaders(tokenValidatedContext.HttpContext.Request.GetTypedHeaders());
            }
            catch (InvalidOperationException)
            {
                // we are not responsible for handling header validation issues
                return;
            }

            // This populates the CurrentAuthenticationContext field for use by us and subsequent controllers
            await authenticationContextFactory.CreateAuthenticationContext(userId, apiHeaders.InstanceId, tokenValidatedContext.SecurityToken.ValidFrom, cancellationToken).ConfigureAwait(false);

            var authenticationContext = authenticationContextFactory.CurrentAuthenticationContext;

            var enumerator = Enum.GetValues(typeof(RightsType));
            var claims     = new List <Claim>();

            foreach (RightsType I in enumerator)
            {
                // if there's no instance user, do a weird thing and add all the instance roles
                // we need it so we can get to OnActionExecutionAsync where we can properly decide between BadRequest and Forbid
                // if user is null that means they got the token with an expired password
                var rightInt  = authenticationContext.User == null || (RightsHelper.IsInstanceRight(I) && authenticationContext.InstanceUser == null) ? ~0U : authenticationContext.GetRight(I);
                var rightEnum = RightsHelper.RightToType(I);
                var right     = (Enum)Enum.ToObject(rightEnum, rightInt);
                foreach (Enum J in Enum.GetValues(rightEnum))
                {
                    if (right.HasFlag(J))
                    {
                        claims.Add(new Claim(ClaimTypes.Role, RightsHelper.RoleName(I, J)));
                    }
                }
            }

            tokenValidatedContext.Principal.AddIdentity(new ClaimsIdentity(claims));
        }