Esempio n. 1
0
        public async Task <TaskResult <PlanetInvite> > CreateInvite(ulong Planet_Id, ulong userid, string token, int hours)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != userid)
            {
                return(new TaskResult <PlanetInvite>(false, "Failed to authorize user.", null));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(Planet_Id, Mapper);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.Invite)))
            {
                return(new TaskResult <PlanetInvite>(false, "You are not authorized to do this.", null));
            }

            PlanetInvite invite = new PlanetInvite()
            {
                Planet_Id = Planet_Id,
                Issuer_Id = userid,
                Time      = DateTime.UtcNow,
                Hours     = hours
            };
            Random random = new Random();

            const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

            string code = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());

            PlanetInvite test = await Context.PlanetInvites.FirstOrDefaultAsync(x => x.Code == code);

            while (test != null)
            {
                code = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());
                test = await Context.PlanetInvites.Where(x => x.Code == code).FirstOrDefaultAsync();
            }

            invite.Code = code;

            if (hours == 0)
            {
                invite.Hours = null;
            }

            await Context.PlanetInvites.AddAsync(invite);

            await Context.SaveChangesAsync();

            return(new TaskResult <PlanetInvite>(true, $"Successfully created invite", invite));
        }
Esempio n. 2
0
        public async Task <TaskResult> BanUser(ulong target_id, ulong planet_id, string reason, string token, uint time)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            if (authToken == null)
            {
                return(new TaskResult(false, "Failed to authorize user."));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.Ban)))
            {
                return(new TaskResult(false, "You are not authorized to do this."));
            }

            ServerPlanetMember member = await Context.PlanetMembers.FirstOrDefaultAsync(x => x.Id == target_id &&
                                                                                        x.Planet_Id == planet_id);

            PlanetBan ban = new PlanetBan()
            {
                Id        = IdManager.Generate(),
                Reason    = reason,
                Planet_Id = planet_id,
                User_Id   = member.User_Id,
                Banner_Id = authToken.User_Id,
                Time      = DateTime.UtcNow,
                Permanent = false
            };

            if (time <= 0)
            {
                ban.Permanent = true;
            }
            else
            {
                ban.Minutes = time;
            }

            // Add channel to database
            await Context.PlanetBans.AddAsync(ban);

            List <ServerPlanetRoleMember> roles = await Task.Run(() => Context.PlanetRoleMembers.Where(x => x.Member_Id == target_id && x.Planet_Id == planet_id).ToList());

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

            Context.PlanetMembers.Remove(member);
            await Context.SaveChangesAsync();

            return(new TaskResult(true, $"Successfully banned user {member.Nickname}"));
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a server and if successful returns a task result with the created
        /// planet's id
        /// </summary>
        public async Task <TaskResult <ulong> > CreateChannel(string name, ulong planet_id, ulong user_id, ulong parentid, string token)
        {
            TaskResult nameValid = ValidateName(name);

            if (!nameValid.Success)
            {
                return(new TaskResult <ulong>(false, nameValid.Message, 0));
            }

            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != user_id)
            {
                return(new TaskResult <ulong>(false, "Failed to authorize user.", 0));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.ManageChannels)))
            {
                return(new TaskResult <ulong>(false, "You are not authorized to do this.", 0));
            }

            // User is verified and given channel info is valid by this point

            // Creates the channel channel

            PlanetChatChannel channel = new PlanetChatChannel()
            {
                Id            = IdManager.Generate(),
                Name          = name,
                Planet_Id     = planet_id,
                Parent_Id     = parentid,
                Message_Count = 0,
                Description   = "A chat channel",
                Position      = Convert.ToUInt16(Context.PlanetChatChannels.Count())
            };

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

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

            await PlanetHub.Current.Clients.Group($"p-{planet_id}").SendAsync("RefreshChannelList", "");

            // Return success
            return(new TaskResult <ulong>(true, "Successfully created channel.", channel.Id));
        }
        /// <summary>
        /// Returns a planet's primary channel
        /// </summary>
        public async Task <TaskResult <PlanetChatChannel> > GetPrimaryChannel(ulong planetid, ulong userid, string token)
        {
            ServerPlanet planet = await ServerPlanet.FindAsync(planetid, Mapper);

            if (!(await planet.AuthorizedAsync(userid, token)))
            {
                return(new TaskResult <PlanetChatChannel>(false, "You are not authorized to access this planet.", null));
            }

            return(new TaskResult <PlanetChatChannel>(true, "Successfully retireved channel.", await planet.GetPrimaryChannelAsync()));
        }
Esempio n. 5
0
        private static async Task GetMemberInfo(HttpContext ctx, ValourDB db,
                                                [FromHeader] string authorization, [Required] ulong planet_id)
        {
            ServerAuthToken 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).ThenInclude(x => x.User)
                                  .Include(x => x.Members).ThenInclude(x => x.RoleMembership.OrderBy(x => x.Role.Position))
                                  .ThenInclude(x => x.Role)
                                  .FirstOrDefaultAsync(x => x.Id == planet_id);

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

                return;
            }

            if (!planet.Members.Any(x => x.User_Id == auth.User_Id))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Member not found");

                return;
            }

            List <PlanetMemberInfo> info = new List <PlanetMemberInfo>();

            foreach (var member in planet.Members)
            {
                PlanetMemberInfo planetInfo = new PlanetMemberInfo()
                {
                    Member  = member,
                    User    = member.User,
                    RoleIds = member.RoleMembership.Select(x => x.Role_Id),
                    State   = "Currently browsing"
                };

                info.Add(planetInfo);
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(info);
        }
Esempio n. 6
0
        public async Task <TaskResult> UpdateOrder([FromBody] Dictionary <ushort, List <ulong> > json, ulong user_id, string token, ulong Planet_Id)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != user_id)
            {
                return(new TaskResult(false, "Failed to authorize user."));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(Planet_Id);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.ManageChannels)))
            {
                return(new TaskResult(false, "You are not authorized to do this."));
            }

            Console.WriteLine(json);
            var values = json;//JsonConvert.DeserializeObject<Dictionary<ulong, ulong>>(data);

            foreach (var value in values)
            {
                ushort position = value.Key;
                ulong  id       = value.Value[0];

                //checks if item is a channel
                Console.WriteLine(value.Value[0]);
                if (value.Value[1] == 0)
                {
                    PlanetChatChannel channel = await Context.PlanetChatChannels.Where(x => x.Id == id).FirstOrDefaultAsync();

                    channel.Position = position;
                }
                if (value.Value[1] == 1)
                {
                    PlanetCategory category = await Context.PlanetCategories.Where(x => x.Id == id).FirstOrDefaultAsync();

                    category.Position = position;
                }

                Console.WriteLine(value);
            }
            await Context.SaveChangesAsync();

            await PlanetHub.Current.Clients.Group($"p-{Planet_Id}").SendAsync("RefreshChannelList", "");

            return(new TaskResult(true, "Updated Order!"));
        }
Esempio n. 7
0
        public async Task <TaskResult <PlanetInvite> > CreateInvite(ulong Planet_Id, string token, int hours)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            if (authToken == null)
            {
                return(new TaskResult <PlanetInvite>(false, "Failed to authorize user.", null));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(Planet_Id);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.Invite)))
            {
                return(new TaskResult <PlanetInvite>(false, "You are not authorized to do this.", null));
            }

            PlanetInvite invite = new PlanetInvite()
            {
                Id        = IdManager.Generate(),
                Planet_Id = Planet_Id,
                Issuer_Id = authToken.User_Id,
                Time      = DateTime.UtcNow,
                Hours     = hours
            };

            Random random = new Random();

            const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

            string code = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());

            PlanetInvite test = await Context.PlanetInvites.FirstOrDefaultAsync(x => x.Code == code);

            while (test != null)
            {
                code = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());
                test = await Context.PlanetInvites.Where(x => x.Code == code).FirstOrDefaultAsync();
            }

            invite.Code = code;

            if (hours == 0)
            {
                invite.Hours = null;
            }

            await Context.PlanetInvites.AddAsync(invite);

            await Context.SaveChangesAsync();

            return(new TaskResult <PlanetInvite>(true, $"Successfully created invite", invite));
        }
Esempio n. 8
0
        public async Task <TaskResult> BanUser(ulong id, ulong Planet_Id, string reason, ulong userid, string token, uint time)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != userid)
            {
                return(new TaskResult(false, "Failed to authorize user."));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(Planet_Id, Mapper);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.Ban)))
            {
                return(new TaskResult(false, "You are not authorized to do this."));
            }

            PlanetBan ban = new PlanetBan()
            {
                Reason    = reason,
                Planet_Id = Planet_Id,
                User_Id   = id,
                Banner_Id = userid,
                Time      = DateTime.UtcNow,
                Permanent = false
            };

            if (time <= 0)
            {
                ban.Permanent = true;
            }
            else
            {
                ban.Minutes = time;
            }

            // Add channel to database
            await Context.PlanetBans.AddAsync(ban);

            PlanetMember member = await Context.PlanetMembers.Where(x => x.User_Id == id).FirstOrDefaultAsync();

            Context.PlanetMembers.Remove(member);
            await Context.SaveChangesAsync();

            return(new TaskResult(true, $"Successfully banned user {id}"));
        }
Esempio n. 9
0
        private static async Task GetChannelIds(HttpContext ctx, ValourDB db,
                                                [FromHeader] string authorization, [Required] ulong planet_id)
        {
            ServerAuthToken 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))
                                  .Include(x => x.ChatChannels)
                                  .FirstOrDefaultAsync(x => x.Id == planet_id);

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

                return;
            }

            var member = planet.Members.FirstOrDefault();

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

                return;
            }

            List <ulong> result = new List <ulong>();

            foreach (var channel in planet.ChatChannels)
            {
                if (await channel.HasPermission(member, ChatChannelPermissions.View, db))
                {
                    result.Add(channel.Id);
                }
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(result);
        }
Esempio n. 10
0
        /// <summary>
        /// Creates a server and if successful returns a task result with the created
        /// planet's id
        /// </summary>
        public async Task <TaskResult <ulong> > CreateCategory(string name, ulong userid, ulong parentid, ulong planet_id, string token)
        {
            TaskResult nameValid = ValidateName(name);

            if (!nameValid.Success)
            {
                return(new TaskResult <ulong>(false, nameValid.Message, 0));
            }

            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != userid)
            {
                return(new TaskResult <ulong>(false, "Failed to authorize user.", 0));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id, Mapper);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.ManageCategories)))
            {
                return(new TaskResult <ulong>(false, "You are not authorized to do this.", 0));
            }

            // User is verified and given channel info is valid by this point

            // Creates the channel channel

            PlanetCategory category = new PlanetCategory()
            {
                Name      = name,
                Planet_Id = planet_id,
                Parent_Id = parentid
            };

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

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

            // Return success
            return(new TaskResult <ulong>(true, "Successfully created category.", category.Id));
        }
Esempio n. 11
0
        /// <summary>
        /// Sets the description of a planet
        /// </summary>
        public async Task <TaskResult> SetDescription(ulong planet_id, string description, string token)
        {
            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id, Mapper);

            if (!(await planet.AuthorizedAsync(token, PlanetPermissions.Manage)))
            {
                return(new TaskResult(false, "You are not authorized to manage this planet."));
            }

            planet.Description = description;

            Context.Planets.Update(planet);
            await Context.SaveChangesAsync();

            return(new TaskResult(true, "Changed description successfully"));
        }
Esempio n. 12
0
        /// <summary>
        /// Returns a planet object (if permitted)
        /// </summary>
        public async Task <TaskResult <Planet> > GetPlanet(ulong planetid, ulong userid, string token)
        {
            ServerPlanet planet = await ServerPlanet.FindAsync(planetid, Mapper);

            if (planet == null)
            {
                return(new TaskResult <Planet>(false, "The given planet id does not exist.", null));
            }

            if (!(await planet.AuthorizedAsync(userid, token)))
            {
                return(new TaskResult <Planet>(false, "You are not authorized to access this planet.", null));
            }

            return(new TaskResult <Planet>(true, "Successfully retrieved planet.", planet));
        }
Esempio n. 13
0
        /// <summary>
        /// Sets the description of a planet
        /// </summary>
        public async Task <TaskResult> SetPublic(ulong planet_id, bool ispublic, string token)
        {
            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id);

            if (!(await planet.AuthorizedAsync(token, PlanetPermissions.Manage)))
            {
                return(new TaskResult(false, "You are not authorized to manage this planet."));
            }

            planet.Public = ispublic;

            Context.Planets.Update(planet);
            await Context.SaveChangesAsync();

            return(new TaskResult(true, "Changed public value successfully"));
        }
Esempio n. 14
0
        public async Task <TaskResult> Delete(ulong id, ulong user_id, string token)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != user_id)
            {
                return(new TaskResult(false, "Failed to authorize user."));
            }

            PlanetChatChannel channel = await Context.PlanetChatChannels.FindAsync(id);

            if (channel == null)
            {
                return(new TaskResult(false, "That channel does not exist."));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(channel.Planet_Id);

            if (planet == null)
            {
                return(new TaskResult(false, "Could not find the planet."));
            }

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.ManageChannels)))
            {
                return(new TaskResult(false, "You are not authorized to do this."));
            }

            if (channel.Id == planet.Main_Channel_Id)
            {
                return(new TaskResult(false, "You can not delete your main channel!"));
            }


            Context.PlanetChatChannels.Remove(channel);

            await Context.SaveChangesAsync();

            await PlanetHub.Current.Clients.Group($"p-{channel.Planet_Id}").SendAsync("RefreshChannelList", "");

            return(new TaskResult(true, "Successfully deleted."));
        }
Esempio n. 15
0
        private static async Task GetRoles(HttpContext ctx, ValourDB db, ulong planet_id,
                                           [FromHeader] string authorization)
        {
            ServerAuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync($"Token is invalid");

                return;
            }

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

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

                return;
            }

            var member = planet.Members.FirstOrDefault();

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

                return;
            }

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

                return;
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(planet.Roles);
        }
Esempio n. 16
0
        /// <summary>
        /// Returns the planet membership of a user
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task <TaskResult <List <Planet> > > GetPlanetMembership(ulong user_id, string token)
        {
            if (token == null)
            {
                return(new TaskResult <List <Planet> >(false, "Please supply an authentication token", null));
            }

            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            if (!Permission.HasPermission(authToken.Scope, UserPermissions.Membership))
            {
                return(new TaskResult <List <Planet> >(false, $"The given token does not have membership scope", null));
            }

            User user = await Context.Users.FindAsync(user_id);

            if (user == null)
            {
                return(new TaskResult <List <Planet> >(false, $"Could not find user {user_id}", null));
            }

            List <Planet> membership = new List <Planet>();

            ServerPlanet valourServer = await ServerPlanet.FindAsync(735703679107072);

            if (valourServer != null)
            {
                // Remove this after pre-pre-alpha
                if (!(await valourServer.IsMemberAsync(user_id, Context)))
                {
                    await valourServer.AddMemberAsync(user, Context);
                }
            }

            foreach (PlanetMember member in Context.PlanetMembers.Where(x => x.User_Id == user_id))
            {
                Planet planet = await Context.Planets.FindAsync(member.Planet_Id);

                if (planet != null)
                {
                    membership.Add(planet);
                }
            }

            return(new TaskResult <List <Planet> >(true, $"Retrieved {membership.Count} planets", membership));
        }
Esempio n. 17
0
        /// <summary>
        /// Returns a planetuser given the user and planet id
        /// </summary>
        public async Task <TaskResult <PlanetUser> > GetPlanetUser(ulong userid, ulong planet_id, string auth)
        {
            // Retrieve planet
            ServerPlanet planet = ServerPlanet.FromBase(await Context.Planets.FindAsync(planet_id), Mapper);

            if (planet == null)
            {
                return(new TaskResult <PlanetUser>(false, "The planet could not be found.", null));
            }

            // Authentication flow
            AuthToken token = await Context.AuthTokens.FindAsync(auth);

            // If authorizor is not a member of the planet, they do not have authority to get member info
            if (token == null || !(await planet.IsMemberAsync(token.User_Id)))
            {
                return(new TaskResult <PlanetUser>(false, "Failed to authorize.", null));
            }

            // At this point the request is authorized

            // Retrieve server data for user
            User user = await Context.Users.FindAsync(userid);

            // Null check
            if (user == null)
            {
                return(new TaskResult <PlanetUser>(false, "The user could not be found.", null));
            }

            // Ensure the user is a member of the planet
            if (!(await planet.IsMemberAsync(user)))
            {
                return(new TaskResult <PlanetUser>(false, "The target user is not a member of the planet.", null));
            }

            PlanetUser planetUser = await ServerPlanetUser.CreateAsync(userid, planet_id, Mapper);

            if (planetUser == null)
            {
                return(new TaskResult <PlanetUser>(false, "Could not create planet user: Fatal error.", null));
            }

            return(new TaskResult <PlanetUser>(true, "Successfully retrieved planet user.", planetUser));
        }
Esempio n. 18
0
        /// <summary>
        /// Returns a planet object (if permitted)
        /// </summary>
        public async Task <TaskResult <Planet> > GetPlanet(ulong planet_id, string token)
        {
            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id);

            if (planet == null)
            {
                return(new TaskResult <Planet>(false, "The given planet id does not exist.", null));
            }

            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.View)))
            {
                return(new TaskResult <Planet>(false, "You are not authorized to access this planet.", null));
            }

            return(new TaskResult <Planet>(true, "Successfully retrieved planet.", planet));
        }
Esempio n. 19
0
        /// <summary>
        /// Returns the planet name using an invite code as authorization
        /// </summary>
        public async Task <TaskResult <string> > GetPlanetName(string invite_code)
        {
            PlanetInvite invite = await Context.PlanetInvites.FirstOrDefaultAsync(x => x.Code == invite_code);

            if (invite == null)
            {
                return(new TaskResult <string>(false, "Could not find invite.", null));
            }

            ServerPlanet planet = await Context.Planets.FindAsync(invite.Planet_Id);

            if (planet == null)
            {
                return(new TaskResult <string>(false, $"Could not find planet {invite.Planet_Id}", null));
            }

            return(new TaskResult <string>(true, $"Success", planet.Name));
        }
Esempio n. 20
0
        public async Task <TaskResult> Delete(ulong id, ulong userid, string token)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != userid)
            {
                return(new TaskResult(false, "Failed to authorize user."));
            }

            PlanetCategory category = await Context.PlanetCategories.FindAsync(id);

            ServerPlanet planet = await ServerPlanet.FindAsync(category.Planet_Id, Mapper);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.ManageCategories)))
            {
                return(new TaskResult(false, "You are not authorized to do this."));
            }

            List <PlanetCategory> categories = await Task.Run(() => Context.PlanetCategories.Where(x => x.Parent_Id == id).ToList());

            foreach (PlanetCategory Category in categories)
            {
                Category.Parent_Id = null;
            }
            List <PlanetChatChannel> channels = await Task.Run(() => Context.PlanetChatChannels.Where(x => x.Parent_Id == id).ToList());

            foreach (PlanetChatChannel channel in channels)
            {
                Context.PlanetChatChannels.Remove(channel);
            }

            Context.PlanetCategories.Remove(category);

            Context.PlanetCategories.Remove(category);
            await Context.SaveChangesAsync();

            return(new TaskResult(true, "Successfully deleted."));
        }
Esempio n. 21
0
        public async Task <TaskResult <List <PlanetInvite> > > GetInvites(ulong user_id, string token, ulong planet_id)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            if (authToken == null)
            {
                return(new TaskResult <List <PlanetInvite> >(false, "Failed to authorize user.", null));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.Invite)))
            {
                return(new TaskResult <List <PlanetInvite> >(false, "You are not authorized to do this.", null));
            }

            List <PlanetInvite> invites = await Task.Run(() => Context.PlanetInvites.Where(x => x.Planet_Id == planet_id).ToList());

            return(new TaskResult <List <PlanetInvite> >(true, $"Retrieved {invites.Count} invites", invites));
        }
Esempio n. 22
0
        public async Task <TaskResult> Join(string code, string token)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            if (authToken == null)
            {
                return(new TaskResult(false, $"Unable to authorize"));
            }

            ulong user_id = authToken.User_Id;

            PlanetInvite invite = await Context.PlanetInvites.FirstOrDefaultAsync(x => x.Code == code);

            if (invite == null)
            {
                return(new TaskResult(false, $"Invite code not found!"));
            }

            if (await Context.PlanetBans.AnyAsync(x => x.User_Id == user_id && x.Planet_Id == invite.Planet_Id))
            {
                return(new TaskResult(false, $"User is banned from this planet!"));
            }

            if (await Context.PlanetMembers.AnyAsync(x => x.User_Id == user_id && x.Planet_Id == invite.Planet_Id))
            {
                return(new TaskResult(false, $"User is already in this planet!"));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(invite.Planet_Id);

            if (!planet.Public)
            {
                return(new TaskResult(false, $"Planet is set to private!"));
            }

            User user = await Context.Users.FindAsync(user_id);

            await planet.AddMemberAsync(user, Context);

            return(new TaskResult(true, $"Successfully joined planet."));
        }
Esempio n. 23
0
        public async Task <TaskResult> SetParentId(ulong id, ulong parentId, ulong user_id, string token)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // Return the same if the token is for the wrong user to prevent someone
            // from knowing if they cracked another user's token. This is basically
            // impossible to happen by chance but better safe than sorry in the case that
            // the literal impossible odds occur, more likely someone gets a stolen token
            // but is not aware of the owner but I'll shut up now - Spike
            if (authToken == null || authToken.User_Id != user_id)
            {
                return(new TaskResult(false, "Failed to authorize user."));
            }

            PlanetCategory category = await Context.PlanetCategories.Where(x => x.Id == id).FirstOrDefaultAsync();

            ServerPlanet planet = await ServerPlanet.FindAsync(category.Planet_Id);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.ManageCategories)))
            {
                return(new TaskResult(false, "You are not authorized to do this."));
            }

            if (parentId == 0)
            {
                category.Parent_Id = null;
            }
            else
            {
                category.Parent_Id = parentId;
            }

            await Context.SaveChangesAsync();

            await PlanetHub.Current.Clients.Group($"p-{planet.Id}").SendAsync("RefreshChannelList", "");

            return(new TaskResult(true, "Successfully set parent id."));
        }
Esempio n. 24
0
        /// <summary>
        /// Sets the name of a planet
        /// </summary>
        public async Task <TaskResult> SetName(ulong planet_id, string name, string token)
        {
            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id);

            if (!(await planet.AuthorizedAsync(token, PlanetPermissions.Manage)))
            {
                return(new TaskResult(false, "You are not authorized to manage this planet."));
            }

            TaskResult validation = ValidateName(name);

            if (!validation.Success)
            {
                return(validation);
            }

            planet.Name = name;

            Context.Planets.Update(planet);
            await Context.SaveChangesAsync();

            return(new TaskResult(true, "Changed name successfully"));
        }
Esempio n. 25
0
        public async Task <TaskResult> KickUser(ulong target_id, ulong planet_id, string token)
        {
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            if (authToken == null)
            {
                return(new TaskResult(false, "Failed to authorize user."));
            }

            ServerPlanet planet = await ServerPlanet.FindAsync(planet_id);

            if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.Kick)))
            {
                return(new TaskResult(false, "You are not authorized to do this."));
            }

            ServerPlanetMember member = await Context.PlanetMembers.FirstOrDefaultAsync(x => x.Id == target_id && x.Planet_Id == planet_id);

            if (member == null)
            {
                return(new TaskResult(true, $"Could not find PlanetMember {target_id}"));
            }

            List <ServerPlanetRoleMember> roles = await Task.Run(() => Context.PlanetRoleMembers.Where(x => x.Member_Id == target_id && x.Planet_Id == planet_id).ToList());

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

            Context.PlanetMembers.Remove(member);

            await Context.SaveChangesAsync();

            return(new TaskResult(true, $"Successfully kicked user {target_id}"));
        }
Esempio n. 26
0
        /// <summary>
        /// Returns a planet member's role ids given the user and planet id
        /// </summary>
        public async Task <TaskResult <List <ulong> > > GetPlanetMemberRoleIds(ulong user_id, ulong planet_id, string token)
        {
            // Retrieve planet
            ServerPlanet planet = ServerPlanet.FromBase(await Context.Planets.FindAsync(planet_id));

            if (planet == null)
            {
                return(new TaskResult <List <ulong> >(false, "The planet could not be found.", null));
            }

            // Authentication flow
            AuthToken authToken = await Context.AuthTokens.FindAsync(token);

            // If authorizor is not a member of the planet, they do not have authority to get member info
            if (authToken == null || !(await planet.IsMemberAsync(authToken.User_Id)))
            {
                return(new TaskResult <List <ulong> >(false, "Failed to authorize.", null));
            }

            var roles   = Context.PlanetRoleMembers.Include(x => x.Role).Where(x => x.User_Id == user_id && x.Planet_Id == planet_id).OrderBy(x => x.Role.Position);
            var roleids = roles.Select(x => x.Role_Id).ToList();

            return(new TaskResult <List <ulong> >(true, $"Retrieved {roleids.Count} roles.", roleids));
        }
Esempio n. 27
0
        private static async Task InsertItem(HttpContext ctx, ValourDB db, ulong category_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;
            }

            ServerPlanetCategory category = await db.PlanetCategories.Include(x => x.Planet)
                                            .ThenInclude(x => x.Members.Where(x => x.User_Id == auth.User_Id))
                                            .FirstOrDefaultAsync(x => x.Id == category_id);

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

                return;
            }

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

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

                return;
            }

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

                return;
            }

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

                return;
            }

            if (!await category.HasPermission(member, CategoryPermissions.ManageCategory, db))
            {
                ctx.Response.StatusCode = 401;
                await ctx.Response.WriteAsync("Member lacks CategoryPermissions.ManageCategory");

                return;
            }

            ChannelListItem in_item = await JsonSerializer.DeserializeAsync <ChannelListItem>(ctx.Request.Body);

            if (in_item == null || in_item.Planet_Id == 0)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync("Include item data.");

                return;
            }

            IServerChannelListItem item = await IServerChannelListItem.FindAsync(in_item.ItemType, in_item.Id, db);

            if (item == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Item not found [id: {in_item.Id}]");

                return;
            }

            ServerPlanet item_planet = await db.Planets.FindAsync(item.Planet_Id);

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

                return;
            }

            if (item_planet.Id != category.Planet_Id)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Item belongs to different planet");

                return;
            }

            if (item.Parent_Id == category.Id)
            {
                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsync($"No change");

                return;
            }

            // Ensure that if this is a category, it is not going into a category that contains itself!
            if (item.ItemType == ItemType.Category)
            {
                ulong?parent_id = category.Parent_Id;

                while (parent_id != null)
                {
                    // Recursion is a nono
                    if (parent_id == item.Id)
                    {
                        ctx.Response.StatusCode = 400;
                        await ctx.Response.WriteAsync("Operation would result in recursion.");

                        return;
                    }

                    parent_id = (await db.PlanetCategories.FindAsync(parent_id)).Parent_Id;
                }
            }

            item.Parent_Id = category.Id;
            item.Position  = in_item.Position;

            db.Update(item);
            await db.SaveChangesAsync();

            item.NotifyClientsChange();

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

            return;
        }
Esempio n. 28
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);
        }
Esempio n. 29
0
        private static async Task Public(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":
            {
                ctx.Response.StatusCode = 200;
                await ctx.Response.WriteAsJsonAsync(planet.Public);

                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();

                bool parsed = false;
                parsed = bool.TryParse(body, out var in_public);

                if (!parsed)
                {
                    ctx.Response.StatusCode = 400;
                    await ctx.Response.WriteAsync("Failed to parse body");

                    return;
                }

                var result = await planet.TrySetPublicAsync(in_public, db);

                if (!result.Success)
                {
                    ctx.Response.StatusCode = 400;
                }
                else
                {
                    ctx.Response.StatusCode = 200;
                }

                await ctx.Response.WriteAsync(result.Message);

                return;
            }
            }
        }
Esempio n. 30
0
        private static async Task CreateCategory(HttpContext ctx, ValourDB db,
                                                 [FromHeader] string authorization)
        {
            ServerPlanetCategory category_data = await JsonSerializer.DeserializeAsync <ServerPlanetCategory>(ctx.Request.Body);

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

                return;
            }

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

                return;
            }

            // Request parameter validation //

            TaskResult name_valid = ServerPlanetCategory.ValidateName(category_data.Name);

            if (!name_valid.Success)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Name is not valid [name: {category_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 == category_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

            ulong?parent_id = null;

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

            ushort child_count = 0;

            if (parent != null)
            {
                parent_id = parent.Id;

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

                    return;
                }

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

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

            // Request action //

            // Creates the category

            ServerPlanetCategory category = new ServerPlanetCategory()
            {
                Id          = IdManager.Generate(),
                Name        = category_data.Name,
                Planet_Id   = category_data.Planet_Id,
                Parent_Id   = category_data.Parent_Id,
                Description = category_data.Description,
                Position    = child_count
            };

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

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

            // Send channel refresh
            PlanetHub.NotifyCategoryChange(category);

            ctx.Response.StatusCode = 201;
            await ctx.Response.WriteAsync(category.Id.ToString());
        }