Exemple #1
0
        public async Task <ChatChannelPermissionsNode> GetChannelNodeAsync(ServerPlanetChatChannel channel, ValourDB db = null)
        {
            bool createdb = false;

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

            var res = await db.ChatChannelPermissionsNodes.FirstOrDefaultAsync(x => x.Channel_Id == channel.Id &&
                                                                               x.Role_Id == Id);

            if (createdb)
            {
                await db.DisposeAsync();
            }

            return(res);
        }
Exemple #2
0
        private static async Task CreateChannel(HttpContext ctx, ValourDB db,
                                                [FromHeader] string authorization)
        {
            ServerPlanetChatChannel channel_data =
                await JsonSerializer.DeserializeAsync <ServerPlanetChatChannel>(ctx.Request.Body);

            if (channel_data == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Please include channel in body");

                return;
            }

            if (string.IsNullOrWhiteSpace(channel_data.Name))
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Please include a channel name");

                return;
            }

            // Request parameter validation //

            TaskResult name_valid = ServerPlanetChatChannel.ValidateName(channel_data.Name);

            if (!name_valid.Success)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Name is not valid [name: {channel_data.Name}]");

                return;
            }

            // Request authorization //

            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (!auth.HasScope(UserPermissions.PlanetManagement))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Token lacks UserPermissions.PlanetManagement scope");

                return;
            }

            ServerPlanet planet = await db.Planets.Include(x => x.Members.Where(x => x.User_Id == auth.User_Id))
                                  .FirstOrDefaultAsync(x => x.Id == channel_data.Planet_Id);

            var member = planet.Members.FirstOrDefault();

            if (!await planet.HasPermissionAsync(member, PlanetPermissions.ManageChannels, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks PlanetPermissions.ManageChannels node");

                return;
            }

            // Ensure parent category exists

            ServerPlanetCategory parent = await db.PlanetCategories.FindAsync(channel_data.Parent_Id);

            if (parent == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Could not find parent");

                return;
            }

            if (parent.Planet_Id != planet.Id)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Parent id does not match planet");

                return;
            }

            // Request action //

            // Creates the channel

            ushort child_count = 0;

            child_count += (ushort)await db.PlanetChatChannels.CountAsync(x => x.Parent_Id == channel_data.Parent_Id);

            child_count += (ushort)await db.PlanetCategories.CountAsync(x => x.Parent_Id == channel_data.Parent_Id);

            ServerPlanetChatChannel channel = new ServerPlanetChatChannel()
            {
                Id            = IdManager.Generate(),
                Name          = channel_data.Name,
                Planet_Id     = channel_data.Planet_Id,
                Parent_Id     = channel_data.Parent_Id,
                Message_Count = 0,
                Description   = channel_data.Description,
                Position      = child_count
            };

            // Add channel to database
            await db.PlanetChatChannels.AddAsync(channel);

            // Save changes to DB
            await db.SaveChangesAsync();

            // Send channel refresh
            PlanetHub.NotifyChatChannelChange(channel);

            ctx.Response.StatusCode = 201;
            await ctx.Response.WriteAsync(channel.Id.ToString());
        }
Exemple #3
0
        private static async Task Create(HttpContext ctx, ValourDB db,
                                         [FromHeader] string authorization, [Required] string name,
                                         [Required] string image_url)
        {
            ServerAuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Token is invalid [token: {authorization}]");

                return;
            }

            TaskResult nameValid = ServerPlanet.ValidateName(name);

            if (!nameValid.Success)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync(nameValid.Message);

                return;
            }

            ServerUser user = await db.Users.FindAsync(auth.User_Id);

            if (!user.Valour_Staff)
            {
                var owned_planets = await db.Planets.CountAsync(x => x.Owner_Id == user.Id);

                if (owned_planets > MAX_OWNED_PLANETS)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync("Max owned planets reached");

                    return;
                }
            }

            // Image handling via proxy
            ProxyResponse proxyResponse = await MPSManager.GetProxy(image_url);

            bool is_media = MPSManager.Media_Types.Contains(proxyResponse.Item.Mime_Type);

            if (proxyResponse.Item == null || !is_media)
            {
                image_url = "https://valour.gg/image.png";
            }
            else
            {
                image_url = proxyResponse.Item.Url;
            }

            ulong planet_id = IdManager.Generate();

            // Create general category
            ServerPlanetCategory category = new ServerPlanetCategory()
            {
                Id          = IdManager.Generate(),
                Name        = "General",
                Parent_Id   = null,
                Planet_Id   = planet_id,
                Description = "General category",
                Position    = 0
            };

            // Create general channel
            ServerPlanetChatChannel channel = new ServerPlanetChatChannel()
            {
                Id            = IdManager.Generate(),
                Planet_Id     = planet_id,
                Name          = "General",
                Message_Count = 0,
                Description   = "General chat channel",
                Parent_Id     = category.Id
            };

            // Create default role
            ServerPlanetRole defaultRole = new ServerPlanetRole()
            {
                Id          = IdManager.Generate(),
                Planet_Id   = planet_id,
                Position    = uint.MaxValue,
                Color_Blue  = 255,
                Color_Green = 255,
                Color_Red   = 255,
                Name        = "@everyone"
            };

            ServerPlanet planet = new ServerPlanet()
            {
                Id              = planet_id,
                Name            = name,
                Member_Count    = 1,
                Description     = "A Valour server.",
                Image_Url       = image_url,
                Public          = true,
                Owner_Id        = user.Id,
                Default_Role_Id = defaultRole.Id,
                Main_Channel_Id = channel.Id
            };

            // Add planet to database
            await db.Planets.AddAsync(planet);

            await db.SaveChangesAsync(); // We must do this first to prevent foreign key errors

            // Add category to database
            await db.PlanetCategories.AddAsync(category);

            // Add channel to database
            await db.PlanetChatChannels.AddAsync(channel);

            // Add default role to database
            await db.PlanetRoles.AddAsync(defaultRole);

            // Save changes
            await db.SaveChangesAsync();

            // Add owner to planet
            await planet.AddMemberAsync(user, db);

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(planet.Id);
        }
Exemple #4
0
        private static async Task PrimaryChannel(HttpContext ctx, ValourDB db, ulong planet_id,
                                                 [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Token is invalid [token: {authorization}]");

                return;
            }

            ServerPlanet planet = await db.Planets.Include(x => x.Members.Where(x => x.User_Id == auth.User_Id))
                                  .FirstOrDefaultAsync(x => x.Id == planet_id);

            if (planet == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Planet not found [id: {planet_id}]");

                return;
            }

            ServerPlanetMember member = planet.Members.FirstOrDefault();

            if (member == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Member not found");

                return;
            }

            if (!await planet.HasPermissionAsync(member, PlanetPermissions.View, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks PlanetPermissions.View");

                return;
            }

            switch (ctx.Request.Method)
            {
            case "GET":
            {
                ServerPlanetChatChannel mainChannel = await db.PlanetChatChannels.FindAsync(planet.Main_Channel_Id);

                if (mainChannel == null)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync($"Main channel not found [id: {planet.Main_Channel_Id}]\n" +
                                                  $"Bug a developer, this should not happen.");

                    return;
                }

                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsJsonAsync(mainChannel);

                return;
            }

            case "PUT":
            {
                if (!auth.HasScope(UserPermissions.PlanetManagement))
                {
                    ctx.Response.StatusCode = 401;
                    await ctx.Response.WriteAsync($"Token lacks UserPermissions.PlanetManagement");

                    return;
                }

                if (!await planet.HasPermissionAsync(member, PlanetPermissions.Manage, db))
                {
                    ctx.Response.StatusCode = 401;
                    await ctx.Response.WriteAsync("Member lacks PlanetPermissions.Manage");

                    return;
                }

                string body = await ctx.Request.ReadBodyStringAsync();

                ServerPlanetChatChannel in_channel = JsonSerializer.Deserialize <ServerPlanetChatChannel>(body);

                if (in_channel == null)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync($"Could not deserialize channel");

                    return;
                }

                ServerPlanetChatChannel channel = await db.PlanetChatChannels.FindAsync(in_channel.Id);

                if (channel == null)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync($"Could not find channel [id: {in_channel.Id}]");

                    return;
                }

                if (channel.Planet.Id != planet.Id)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync($"Channel belongs to different planet");

                    return;
                }

                planet.Main_Channel_Id = channel.Id;
                await db.SaveChangesAsync();

                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsync("Success");

                return;
            }
            }
        }
Exemple #5
0
 public async Task <PermissionState> GetPermissionStateAsync(Permission permission, ServerPlanetChatChannel channel)
 {
     return(await GetPermissionStateAsync(permission, channel.Id));
 }
Exemple #6
0
        private static async Task GetMessages(HttpContext ctx, ValourDB db, ulong channel_id,
                                              [FromHeader] string authorization,
                                              ulong index = ulong.MaxValue, int count = 10)
        {
            // Request parameter validation //
            if (count > 64)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Max count is 64");

                return;
            }


            // Request authorization //

            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Token is invalid [token: {authorization}]");

                return;
            }

            ServerPlanetChatChannel channel = await db.PlanetChatChannels.Include(x => x.Planet)
                                              .ThenInclude(x => x.Members.Where(x => x.User_Id == auth.User_Id))
                                              .FirstOrDefaultAsync(x => x.Id == channel_id);

            var member = channel.Planet.Members.FirstOrDefault();

            if (member == null || !await channel.HasPermission(member, ChatChannelPermissions.ViewMessages, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks ChatChannelPermissions.ViewMessages node");

                return;
            }

            List <PlanetMessage> staged   = PlanetMessageWorker.GetStagedMessages(channel_id, count);
            List <PlanetMessage> messages = null;

            count = count - staged.Count;

            if (count > 0)
            {
                await Task.Run(() =>
                {
                    messages =
                        db.PlanetMessages.Where(x => x.Channel_Id == channel_id && x.Message_Index < index)
                        .OrderByDescending(x => x.Message_Index)
                        .Take(count)
                        .Reverse()
                        .ToList();
                });

                messages.AddRange(staged.Where(x => x.Message_Index < index));
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(messages);
        }
Exemple #7
0
        private static async Task PostMessage(HttpContext ctx, ValourDB db,
                                              [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Token is invalid [token: {authorization}]");

                return;
            }

            string body = await ctx.Request.ReadBodyStringAsync();

            var message = JsonSerializer.Deserialize <PlanetMessage>(body);

            if (message == null || message.Content == null || message.Fingerprint == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Include message data");

                return;
            }

            ServerPlanetChatChannel channel = await db.PlanetChatChannels.Include(x => x.Planet)
                                              .ThenInclude(x => x.Members.Where(x => x.User_Id == auth.User_Id))
                                              .FirstOrDefaultAsync(x => x.Id == message.Channel_Id);

            if (channel == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Channel not found [id: {message.Channel_Id}]");

                return;
            }

            var member = channel.Planet.Members.FirstOrDefault();

            if (member == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Could not find member using token");

                return;
            }

            if (!await channel.HasPermission(member, ChatChannelPermissions.ViewMessages, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks ChatChannelPermissions.ViewMessages node");

                return;
            }

            if (!await channel.HasPermission(member, ChatChannelPermissions.PostMessages, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks ChatChannelPermissions.PostMessages node");

                return;
            }

            // Ensure author id is accurate
            message.Author_Id = auth.User_Id;

            if (message.Content != null && message.Content.Length > 2048)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Content is over 2048 chars");

                return;
            }

            if (message.Embed_Data != null && message.Content.Length > 65535)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Embed is over 65535 chars");

                return;
            }

            // Handle urls
            message.Content = await MPSManager.HandleUrls(message.Content);

            PlanetMessageWorker.AddToQueue(message);

            StatWorker.IncreaseMessageCount();

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsync("Success");
        }
Exemple #8
0
        private static async Task ParentId(HttpContext ctx, ValourDB db, ulong channel_id,
                                           [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Token is invalid [token: {authorization}]");

                return;
            }

            ServerPlanetChatChannel channel = await db.PlanetChatChannels.Include(x => x.Planet)
                                              .ThenInclude(x => x.Members.Where(x => x.User_Id == auth.User_Id))
                                              .FirstOrDefaultAsync(x => x.Id == channel_id);

            if (channel == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Channel not found [id: {channel_id}]");

                return;
            }

            var member = channel.Planet.Members.FirstOrDefault();

            if (member == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member not found");

                return;
            }

            if (!await channel.HasPermission(member, ChatChannelPermissions.View, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks ChatChannelPermissions.View");

                return;
            }

            switch (ctx.Request.Method)
            {
            case "GET":
            {
                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsJsonAsync(channel.Parent_Id);

                return;
            }

            case "PUT":
            {
                if (!auth.HasScope(UserPermissions.PlanetManagement))
                {
                    ctx.Response.StatusCode = 401;
                    await ctx.Response.WriteAsync($"Token lacks UserPermissions.PlanetManagement");

                    return;
                }

                if (!await channel.HasPermission(member, ChatChannelPermissions.ManageChannel, db))
                {
                    ctx.Response.StatusCode = 401;
                    await ctx.Response.WriteAsync("Member lacks ChatChannelPermissions.ManageChannel");

                    return;
                }

                string body = await ctx.Request.ReadBodyStringAsync();

                ulong parent_id;
                bool  parsed = ulong.TryParse(body, out parent_id);

                if (!parsed)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync("Given value is invalid");

                    return;
                }

                // Ensure parent category exists and belongs to the same planet
                var parent = await db.PlanetCategories.FindAsync(parent_id);

                if (parent == null)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync($"Category not found [id: {parent_id}]");

                    return;
                }

                if (parent.Planet_Id != channel.Planet_Id)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync($"Category belongs to a different planet");

                    return;
                }

                await channel.SetParentAsync(parent_id, db);

                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsync("Success");

                return;
            }
            }
        }
Exemple #9
0
        private static async Task Description(HttpContext ctx, ValourDB db, ulong channel_id,
                                              [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Token is invalid [token: {authorization}]");

                return;
            }

            ServerPlanetChatChannel channel = await db.PlanetChatChannels.Include(x => x.Planet)
                                              .ThenInclude(x => x.Members.Where(x => x.User_Id == auth.User_Id))
                                              .FirstOrDefaultAsync(x => x.Id == channel_id);

            if (channel == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Channel not found [id: {channel_id}]");

                return;
            }

            var member = channel.Planet.Members.FirstOrDefault();

            if (member == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member not found");

                return;
            }

            if (!await channel.HasPermission(member, ChatChannelPermissions.View, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks ChatChannelPermissions.View");

                return;
            }

            switch (ctx.Request.Method)
            {
            case "GET":
            {
                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsJsonAsync(channel.Description);

                return;
            }

            case "PUT":
            {
                if (!auth.HasScope(UserPermissions.PlanetManagement))
                {
                    ctx.Response.StatusCode = 401;
                    await ctx.Response.WriteAsync($"Token lacks UserPermissions.PlanetManagement");

                    return;
                }

                if (!await channel.HasPermission(member, ChatChannelPermissions.ManageChannel, db))
                {
                    ctx.Response.StatusCode = 401;
                    await ctx.Response.WriteAsync("Member lacks ChatChannelPermissions.ManageChannel");

                    return;
                }

                string body = await ctx.Request.ReadBodyStringAsync();

                await channel.SetDescriptionAsync(body, db);

                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsync("Success");

                return;
            }
            }
        }