예제 #1
0
        /// <summary>
        /// Adds a member to the server
        /// </summary>
        public async Task AddMemberAsync(User user, ValourDB db)
        {
            // Already a member
            if (await db.PlanetMembers.AnyAsync(x => x.User_Id == user.Id && x.Planet_Id == Id))
            {
                return;
            }

            ServerPlanetMember member = new ServerPlanetMember()
            {
                Id        = IdManager.Generate(),
                Nickname  = user.Username,
                Planet_Id = Id,
                User_Id   = user.Id
            };

            // Add to default planet role
            ServerPlanetRoleMember rolemember = new ServerPlanetRoleMember()
            {
                Id        = IdManager.Generate(),
                Planet_Id = Id,
                User_Id   = user.Id,
                Role_Id   = Default_Role_Id,
                Member_Id = member.Id
            };

            await db.PlanetMembers.AddAsync(member);

            await db.PlanetRoleMembers.AddAsync(rolemember);

            await db.SaveChangesAsync();

            Console.WriteLine($"User {user.Username} ({user.Id}) has joined {Name} ({Id})");
        }
예제 #2
0
        /// <summary>
        /// Returns if the given user is authorized to access this planet
        /// </summary>
        public async Task <bool> HasPermissionAsync(ServerPlanetMember member, PlanetPermission permission, ValourDB db)
        {
            // Special case for viewing planets
            if (permission.Value == PlanetPermissions.View.Value)
            {
                if (Public || (member != null))
                {
                    return(true);
                }
            }

            // At this point all permissions require membership
            if (member == null)
            {
                return(false);
            }

            // Owner has all permissions
            if (member.User_Id == Owner_Id)
            {
                return(true);
            }

            // Get user main role
            var mainRole = await db.Entry(member).Collection(x => x.RoleMembership)
                           .Query()
                           .Include(x => x.Role)
                           .OrderBy(x => x.Role.Position)
                           .Select(x => x.Role)
                           .FirstAsync();

            // Return permission state
            return(mainRole.HasPermission(permission));
        }
예제 #3
0
        public async Task <bool> HasPermission(ServerPlanetMember member, ChannelPermission permission)
        {
            var roles = await member.GetRolesAsync();

            // Starting from the most important role, we stop once we hit the first clear "TRUE/FALSE".
            // If we get an undecided, we continue to the next role down
            foreach (var role in roles)
            {
                var node = await ServerPlanetRole.FromBase(role).GetChannelNodeAsync(this);

                PermissionState state = node.GetPermissionState(permission);

                if (state == PermissionState.Undefined)
                {
                    continue;
                }
                else if (state == PermissionState.True)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            // No roles ever defined behavior: resort to false.
            return(false);
        }
예제 #4
0
        public async Task <TaskResult <int> > TryKickMemberAsync(ServerPlanetMember member,
                                                                 ServerPlanetMember target, ValourDB db)
        {
            if (member == null)
            {
                return(new TaskResult <int>(false, "Member not found", 404));
            }

            if (!await HasPermissionAsync(member, PlanetPermissions.Kick, db))
            {
                return(new TaskResult <int>(false, "Member lacks PlanetPermissions.View", 403));
            }

            if (target == null)
            {
                return(new TaskResult <int>(false, $"Target not found", 404));
            }

            if (member.Id == target.Id)
            {
                return(new TaskResult <int>(false, "You cannot kick yourself!", 400));
            }

            if (!await HasPermissionAsync(member, PlanetPermissions.Kick, db))
            {
                return(new TaskResult <int>(false, "Member lacks PlanetPermissions.Kick", 403));
            }

            if (await member.GetAuthorityAsync() <= await target.GetAuthorityAsync())
            {
                return(new TaskResult <int>(false, "You can only kick members with lower authority!", 403));
            }

            // Remove roles
            var roles = db.PlanetRoleMembers.Where(x => x.Member_Id == target.Id);

            foreach (ServerPlanetRoleMember role in roles)
            {
                db.PlanetRoleMembers.Remove(role);
            }

            // Remove member
            db.PlanetMembers.Remove(target);

            // Save changes
            await db.SaveChangesAsync();

            return(new TaskResult <int>(true, $"Successfully kicked user", 200));
        }
예제 #5
0
        /// <summary>
        /// Adds a member to the server
        /// </summary>
        public async Task AddMemberAsync(User user, ValourDB db = null)
        {
            // Setup db if none provided
            bool dbcreate = false;

            if (db == null)
            {
                db       = new ValourDB(ValourDB.DBOptions);
                dbcreate = true;
            }

            // Already a member
            if (await db.PlanetMembers.AnyAsync(x => x.User_Id == user.Id && x.Planet_Id == Id))
            {
                return;
            }

            ServerPlanetMember member = new ServerPlanetMember()
            {
                Id        = IdManager.Generate(),
                Nickname  = user.Username,
                Planet_Id = Id,
                User_Id   = user.Id
            };

            // Add to default planet role
            ServerPlanetRoleMember rolemember = new ServerPlanetRoleMember()
            {
                Id        = IdManager.Generate(),
                Planet_Id = Id,
                User_Id   = user.Id,
                Role_Id   = Default_Role_Id,
                Member_Id = member.Id
            };

            await db.PlanetMembers.AddAsync(member);

            await db.PlanetRoleMembers.AddAsync(rolemember);

            await db.SaveChangesAsync();

            Console.WriteLine($"User {user.Username} ({user.Id}) has joined {Name} ({Id})");

            // Clean up if created own db
            if (dbcreate)
            {
                await db.DisposeAsync();
            }
        }
예제 #6
0
        /// <summary>
        /// Deletes this channel
        /// </summary>
        public async Task <TaskResult <int> > TryDeleteAsync(ServerPlanetMember member, ValourDB db)
        {
            Planet ??= await GetPlanetAsync(db);

            if (Id == Planet.Main_Channel_Id)
            {
                return(new TaskResult <int>(false, $"Cannot delete main channel", 400));
            }

            if (member == null)
            {
                return(new TaskResult <int>(false, "Member not found", 403));
            }

            if (!await HasPermission(member, ChatChannelPermissions.View, db))
            {
                return(new TaskResult <int>(false, "Member lacks ChatChannelPermissions.View", 403));
            }

            if (!await HasPermission(member, ChatChannelPermissions.ManageChannel, db))
            {
                return(new TaskResult <int>(false, "Member lacks ChatChannelPermissions.ManageChannel", 403));
            }

            // Remove permission nodes
            db.ChatChannelPermissionsNodes.RemoveRange(
                db.ChatChannelPermissionsNodes.Where(x => x.Channel_Id == Id)
                );

            // Remove messages
            db.PlanetMessages.RemoveRange(
                db.PlanetMessages.Where(x => x.Channel_Id == Id)
                );

            // Remove channel
            db.PlanetChatChannels.Remove(
                await db.PlanetChatChannels.FirstOrDefaultAsync(x => x.Id == Id)
                );

            // Save changes
            await db.SaveChangesAsync();

            // Notify channel deletion
            await PlanetHub.NotifyChatChannelDeletion(this);

            return(new TaskResult <int>(true, "Success", 200));
        }
예제 #7
0
        /// <summary>
        /// Returns if a given member has a channel permission
        /// </summary>
        public async Task <bool> HasPermission(ServerPlanetMember member, ChatChannelPermission permission, ValourDB db)
        {
            Planet ??= await GetPlanetAsync(db);

            if (Planet.Owner_Id == member.User_Id)
            {
                return(true);
            }

            // If true, we just ask the category
            if (Inherits_Perms)
            {
                if (Parent == null)
                {
                    Parent = await GetParentAsync(db);
                }

                return(await Parent.HasPermission(member, permission));
            }


            // Load permission data
            await db.Entry(member).Collection(x => x.RoleMembership)
            .Query()
            .Where(x => x.Planet_Id == Planet.Id)
            .Include(x => x.Role)
            .ThenInclude(x => x.ChatChannelPermissionNodes.Where(x => x.Channel_Id == Id))
            .LoadAsync();

            // Starting from the most important role, we stop once we hit the first clear "TRUE/FALSE".
            // If we get an undecided, we continue to the next role down
            foreach (var roleMembership in member.RoleMembership)
            {
                var role = roleMembership.Role;
                ChatChannelPermissionsNode node = role.ChatChannelPermissionNodes.FirstOrDefault();

                // If we are dealing with the default role and the behavior is undefined, we fall back to the default permissions
                if (node == null)
                {
                    if (role.Id == Planet.Default_Role_Id)
                    {
                        return(Permission.HasPermission(ChatChannelPermissions.Default, permission));
                    }

                    continue;
                }

                PermissionState state = node.GetPermissionState(permission);

                if (state == PermissionState.Undefined)
                {
                    continue;
                }
                else if (state == PermissionState.True)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            // No roles ever defined behavior: resort to false.
            return(false);
        }
예제 #8
0
        public static async void NotifyMemberChange(ServerPlanetMember member)
        {
            string json = JsonSerializer.Serialize(member);

            await Current.Clients.Group($"p-{member.Planet_Id}").SendAsync("MemberUpdate", json);
        }
예제 #9
0
        public async Task <TaskResult <int> > TryBanMemberAsync(ServerPlanetMember member,
                                                                ServerPlanetMember target, string reason, uint?duration, ValourDB db)
        {
            if (member == null)
            {
                return(new TaskResult <int>(false, "Member not found", 404));
            }

            if (!await HasPermissionAsync(member, PlanetPermissions.Kick, db))
            {
                return(new TaskResult <int>(false, "Member lacks PlanetPermissions.View", 403));
            }

            if (target == null)
            {
                return(new TaskResult <int>(false, $"Target not found", 404));
            }

            if (member.Id == target.Id)
            {
                return(new TaskResult <int>(false, "You cannot ban yourself!", 400));
            }

            if (!await HasPermissionAsync(member, PlanetPermissions.Ban, db))
            {
                return(new TaskResult <int>(false, "Member lacks PlanetPermissions.Ban", 403));
            }

            if (await member.GetAuthorityAsync() <= await target.GetAuthorityAsync())
            {
                return(new TaskResult <int>(false, "You can only ban members with lower authority!", 403));
            }

            if (duration == 0)
            {
                duration = null;
            }

            // Add ban to database
            PlanetBan ban = new PlanetBan()
            {
                Id        = IdManager.Generate(),
                Reason    = reason,
                Time      = DateTime.UtcNow,
                Banner_Id = member.User_Id,
                User_Id   = target.User_Id,
                Planet_Id = member.Planet_Id,
                Minutes   = duration
            };

            await db.PlanetBans.AddAsync(ban);

            // Remove roles
            var roles = db.PlanetRoleMembers.Where(x => x.Member_Id == target.Id);

            foreach (ServerPlanetRoleMember role in roles)
            {
                db.PlanetRoleMembers.Remove(role);
            }

            // Remove member
            db.PlanetMembers.Remove(target);

            // Save changes
            await db.SaveChangesAsync();

            return(new TaskResult <int>(true, $"Successfully banned user", 200));
        }