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); }
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()); }
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); }
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; } } }
public async Task <PermissionState> GetPermissionStateAsync(Permission permission, ServerPlanetChatChannel channel) { return(await GetPermissionStateAsync(permission, channel.Id)); }
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); }
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"); }
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; } } }
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; } } }