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

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

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

            await db.PlanetMembers.AddAsync(member);

            await db.PlanetRoleMembers.AddAsync(rolemember);

            await db.SaveChangesAsync();

            Console.WriteLine($"User {user.Username} ({user.Id}) has joined {Name} ({Id})");
        }
示例#2
0
        private static async Task GetAuthority(HttpContext ctx, ValourDB db, ulong member_id,
                                               [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth is null)
            {
                await TokenInvalid(ctx); return;
            }

            ServerPlanetMember target_member = await db.PlanetMembers
                                               .Include(x => x.RoleMembership.OrderBy(x => x.Role.Position))
                                               .ThenInclude(x => x.Role)
                                               .FirstOrDefaultAsync(x => x.Id == member_id);


            if (target_member is null)
            {
                await NotFound("Target member not found", ctx); return;
            }

            // Ensure auth user is member of planet
            ServerPlanetMember auth_member = await db.PlanetMembers.FirstOrDefaultAsync(x => x.Planet_Id == target_member.Planet_Id &&
                                                                                        x.User_Id == auth.User_Id);

            if (auth_member is null)
            {
                await Unauthorized("Auth member not found", ctx); return;
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(await target_member.GetAuthorityAsync());

            return;
        }
示例#3
0
 /// <summary>
 /// Returns the default role for the planet
 /// </summary>
 public async Task <PlanetRole> GetDefaultRole()
 {
     using (ValourDB Context = new ValourDB(ValourDB.DBOptions))
     {
         return(await Context.PlanetRoles.FindAsync(Default_Role_Id));
     }
 }
示例#4
0
        /// <summary>
        /// Validates and returns a User using credentials (async)
        /// </summary>
        public async Task <TaskResult <User> > ValidateAsync(string credential_type, string identifier, string secret)
        {
            using (ValourDB context = new ValourDB(ValourDB.DBOptions))
            {
                // Find the credential that matches the identifier and type
                Credential credential = await context.Credentials.FirstOrDefaultAsync(
                    x => string.Equals(credential_type, x.Credential_Type, StringComparison.OrdinalIgnoreCase) &&
                    string.Equals(identifier, x.Identifier, StringComparison.OrdinalIgnoreCase));

                if (credential == null || string.IsNullOrWhiteSpace(secret))
                {
                    return(new TaskResult <User>(false, "The credentials were incorrect.", null));
                }

                // Use salt to validate secret hash
                byte[] hash = PasswordManager.GetHashForPassword(secret, credential.Salt);

                // Spike needs to remember how reference types work
                if (!hash.SequenceEqual(credential.Secret))
                {
                    return(new TaskResult <User>(false, "The credentials were incorrect.", null));
                }

                User user = await context.Users.FindAsync(credential.User_Id);

                if (user.Disabled)
                {
                    return(new TaskResult <User>(false, "This account has been disabled", null));
                }

                return(new TaskResult <User>(true, "Succeeded", user));
            }
        }
示例#5
0
    private static async Task Interaction(HttpContext ctx, ValourDB db, [FromHeader] string authorization)
    {
        InteractionEvent e = await JsonSerializer.DeserializeAsync <InteractionEvent>(ctx.Request.Body);

        var authToken = await ServerAuthToken.TryAuthorize(authorization, db);

        if (authToken == null)
        {
            await TokenInvalid(ctx); return;
        }

        var member = await db.PlanetMembers.Include(x => x.Planet).FirstOrDefaultAsync(x => x.Id == e.Member_Id);

        if (member == null)
        {
            await NotFound("Member not found", ctx); return;
        }
        if (authToken.User_Id != member.User_Id)
        {
            await BadRequest("Member id mismatch", ctx); return;
        }

        var channel = await db.PlanetChatChannels.FindAsync(e.Channel_Id);

        if (!await channel.HasPermission(member, ChatChannelPermissions.View, db))
        {
            await Unauthorized("Member lacks ChatChannelPermissions.View", ctx); return;
        }

        PlanetHub.NotifyInteractionEvent(e);
    }
示例#6
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                Task task = Task.Run(async() =>
                {
                    //try
                    //{

                    Context = new ValourDB(ValourDB.DBOptions);

                    if (Context != null && System.Diagnostics.Debugger.IsAttached == false)
                    {
                        stats.Time              = DateTime.UtcNow;
                        stats.userCount         = Context.Users.Count();
                        stats.planetCount       = Context.Planets.Count();
                        stats.planetmemberCount = Context.PlanetMembers.Count();
                        stats.channelCount      = Context.PlanetChatChannels.Count();
                        stats.categoryCount     = Context.PlanetCategories.Count();
                        await Context.Stats.AddAsync(stats);
                        await Context.SaveChangesAsync();
                        stats = new StatObject();
                        _logger.LogInformation($"Saved successfully.");
                    }
                });
                while (!task.IsCompleted)
                {
                    _logger.LogInformation($"Stat Worker running at: {DateTimeOffset.Now}");
                    await Task.Delay(60000, stoppingToken);
                }

                _logger.LogInformation("Stat Worker task stopped at: {time}", DateTimeOffset.Now);
                _logger.LogInformation("Restarting.", DateTimeOffset.Now);
            }
        }
示例#7
0
        /// <summary>
        /// Returns all members who can see this channel
        /// </summary>
        public async Task <List <ServerPlanetMember> > GetChannelMembersAsync(ValourDB db = null)
        {
            List <ServerPlanetMember> members = new List <ServerPlanetMember>();

            bool createdb = false;

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

            var planetMembers = db.PlanetMembers.Include(x => x.RoleMembership).Where(x => x.Planet_Id == Planet_Id);

            foreach (var member in planetMembers)
            {
                if (await HasPermission(member, ChatChannelPermissions.View, db))
                {
                    members.Add(member);
                }
            }

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

            return(members);
        }
示例#8
0
文件: UserAPI.cs 项目: Coca162/Valour
        private static async Task GetPlanets(HttpContext ctx, ValourDB db, ulong user_id,
                                             [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth == null)
            {
                await TokenInvalid(ctx); return;
            }
            if (!auth.HasScope(UserPermissions.Membership))
            {
                await Unauthorized("Token lacks UserPermissions.Membership", ctx); return;
            }
            if (auth.User_Id != user_id)
            {
                await Unauthorized("User id does not match token holder", ctx); return;
            }

            ServerUser user = await db.Users
                              .Include(x => x.Membership)
                              .ThenInclude(x => x.Planet)
                              .FirstOrDefaultAsync(x => x.Id == user_id);

            if (user == null)
            {
                await NotFound("User not found", ctx); return;
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(user.Membership.Select(x => x.Planet));
        }
示例#9
0
        private static async Task GetInvites(HttpContext ctx, ValourDB db, ulong planet_id,
                                             [FromHeader] string authorization)
        {
            var authToken = await ServerAuthToken.TryAuthorize(authorization, db);

            if (authToken == null)
            {
                await TokenInvalid(ctx); return;
            }

            ServerPlanetMember member = await db.PlanetMembers
                                        .Include(x => x.Planet)
                                        .ThenInclude(x => x.Invites)
                                        .FirstOrDefaultAsync(x => x.Planet_Id == planet_id && x.User_Id == authToken.User_Id);

            if (member == null)
            {
                await Unauthorized("Member not found", ctx); return;
            }

            if (!await member.HasPermissionAsync(PlanetPermissions.Invite, db))
            {
                await Unauthorized("Member lacks PlanetPermissions.Invite", ctx); return;
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(member.Planet.Invites);
        }
示例#10
0
        /// <summary>
        /// Creates a PlanetUser instance using a user id and planet id
        /// </summary>
        public static async Task <ServerPlanetUser> CreateAsync(ulong userid, ulong planet_id, IMapper mapper)
        {
            using (ValourDB db = new ValourDB(ValourDB.DBOptions))
            {
                // Retrieve user
                User user = await db.Users.FindAsync(userid);

                // Retrieve planet
                ServerPlanet planet = ServerPlanet.FromBase(await db.Planets.FindAsync(planet_id), mapper);

                // TODO: Actually set roles and stuff once roles exist.

                // Ensure user is within planet
                if (!(await planet.IsMemberAsync(user)))
                {
                    return(null);
                }

                // First map the user to a planetUser to copy basic fields
                ServerPlanetUser planetUser = mapper.Map <ServerPlanetUser>(user);

                // Now copy across planet info
                planetUser.Planet_Id = planet_id;

                return(planetUser);
            }
        }
示例#11
0
 public List <ChannelPermissionsNode> GetAllChannelNodes()
 {
     using (ValourDB Context = new ValourDB(ValourDB.DBOptions))
     {
         return(Context.ChannelPermissionsNodes.Where(x => x.Planet_Id == Planet_Id).ToList());
     }
 }
示例#12
0
        /// <summary>
        /// Returns all of the roles for a planet user
        /// </summary>
        public async Task <List <ServerPlanetRole> > GetRolesAsync(ValourDB db = null)
        {
            bool createdb = false;

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

            List <ServerPlanetRole> roles = new List <ServerPlanetRole>();

            // Add default role
            ServerPlanet planet = await ServerPlanet.FindAsync(Planet_Id);

            var membership = db.PlanetRoleMembers.Include(x => x.Role)
                             .Where(x => x.Member_Id == Id)
                             .OrderBy(x => x.Role.Position)
                             .Select(x => x.Role)
                             .ToList();

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

            return(membership);
        }
示例#13
0
        private static async Task KickMember(HttpContext ctx, ValourDB db, ulong planet_id, ulong target_id,
                                             [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth is null)
            {
                Results.Unauthorized();
                return;
            }

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

            if (planet is null)
            {
                ctx.Response.StatusCode = 404;
                await ctx.Response.WriteAsync($"Planet not found");

                return;
            }

            ServerPlanetMember member = planet.Members.FirstOrDefault(x => x.User_Id == auth.User_Id);
            ServerPlanetMember target = planet.Members.FirstOrDefault(x => x.Id == target_id);

            var result = await planet.TryKickMemberAsync(member, target, db);

            ctx.Response.StatusCode = result.Data;
            await ctx.Response.WriteAsync(result.Message);
        }
示例#14
0
 /// <summary>
 /// Returns the planet (async)
 /// </summary>
 public async Task <Planet> GetPlanetAsync()
 {
     using (ValourDB db = new ValourDB(ValourDB.DBOptions))
     {
         return(await db.Planets.FindAsync(Planet_Id));
     }
 }
示例#15
0
        /// <summary>
        /// Returns if the member has the given permission
        /// </summary>
        public async Task <bool> HasPermissionAsync(PlanetPermission permission, ValourDB db = null)
        {
            // Make sure we didn't include the planet already
            if (Planet == null)
            {
                bool createdb = false;
                if (db == null)
                {
                    db       = new ValourDB(ValourDB.DBOptions);
                    createdb = true;
                }

                Planet = await db.Planets.FindAsync(Planet_Id);

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

            // Special case for owner
            if (User_Id == Planet.Owner_Id)
            {
                return(true);
            }

            return((await GetPrimaryRoleAsync(db)).HasPermission(permission));
        }
示例#16
0
 /// <summary>
 /// Returns if a given user id is a member (async)
 /// </summary>
 public async Task <bool> IsMemberAsync(ulong userid)
 {
     using (ValourDB db = new ValourDB(ValourDB.DBOptions))
     {
         return(await db.PlanetMembers.AnyAsync(x => x.Planet_Id == this.Id && x.User_Id == userid));
     }
 }
示例#17
0
文件: RoleAPI.cs 项目: Coca162/Valour
        private static async Task Role(HttpContext ctx, ValourDB db, ulong role_id,
                                       [FromHeader] string authorization)
        {
            AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db);

            if (auth is null)
            {
                await TokenInvalid(ctx); return;
            }

            ServerPlanetRole role = await db.PlanetRoles.FindAsync(role_id);

            if (role == null)
            {
                await NotFound("Role not found.", ctx); return;
            }

            ServerPlanetMember member = await db.PlanetMembers
                                        .Include(x => x.Planet)
                                        .FirstOrDefaultAsync(x => x.Planet_Id == role.Planet_Id &&
                                                             x.User_Id == auth.User_Id);

            if (member == null)
            {
                await NotFound("Member not found", ctx); return;
            }

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

                return;
            }

            case "DELETE":
            {
                var result = await role.TryDeleteAsync(member, db);

                ctx.Response.StatusCode = result.Data;
                await ctx.Response.WriteAsync(result.Message);

                return;
            }

            case "PUT":
            {
                ServerPlanetRole in_role = await JsonSerializer.DeserializeAsync <ServerPlanetRole>(ctx.Response.Body);

                var result = await role.TryUpdateAsync(member, in_role, db);

                ctx.Response.StatusCode = result.Data;
                await ctx.Response.WriteAsync(result.Message);

                return;
            }
            }
        }
示例#18
0
 /// <summary>
 /// Returns the user (async)
 /// </summary>
 public async Task <User> GetUserAsync()
 {
     using (ValourDB db = new ValourDB(ValourDB.DBOptions))
     {
         return(await db.Users.FindAsync(User_Id));
     }
 }
示例#19
0
        private static async Task GetMemberRoleIds(HttpContext ctx, ValourDB db, ulong planet_id, ulong user_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.ToString()}]");

                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;
            }

            ServerPlanetMember target = await db.PlanetMembers.Include(x => x.RoleMembership.OrderBy(x => x.Role.Position))
                                        .ThenInclude(x => x.Role)
                                        .FirstOrDefaultAsync(x => x.Planet_Id == planet_id && x.User_Id == user_id);

            if (target == null)
            {
                ctx.Response.StatusCode = 400;
                await ctx.Response.WriteAsync($"Member not found [user_id: {user_id.ToString()}, planet_id: {planet_id.ToString()}");

                return;
            }

            ctx.Response.StatusCode = 200;
            await ctx.Response.WriteAsJsonAsync(target.RoleMembership.Select(x => x.Role_Id));

            return;
        }
示例#20
0
        /// <summary>
        /// Sets the parent of this channel
        /// </summary>
        public async Task SetParentAsync(ulong parent_id, ValourDB db)
        {
            this.Parent_Id = parent_id;
            db.PlanetChatChannels.Update(this);
            await db.SaveChangesAsync();

            NotifyClientsChange();
        }
示例#21
0
 public static async Task <ServerPlanetMember> FindAsync(ulong user_id, ulong planet_id)
 {
     using (ValourDB db = new ValourDB(ValourDB.DBOptions))
     {
         return(FromBase(await db.PlanetMembers.FirstOrDefaultAsync(x => x.Planet_Id == planet_id &&
                                                                    x.User_Id == user_id)));
     }
 }
示例#22
0
        /// <summary>
        /// Sets the description of this channel
        /// </summary>
        public async Task SetDescriptionAsync(string desc, ValourDB db)
        {
            this.Description = desc;
            db.PlanetChatChannels.Update(this);
            await db.SaveChangesAsync();

            NotifyClientsChange();
        }
示例#23
0
        /// <summary>
        /// Sets the permissions inherit mode of this channel
        /// </summary>
        public async Task SetInheritsPermsAsync(bool inherits_perms, ValourDB db)
        {
            this.Inherits_Perms = inherits_perms;
            db.PlanetChatChannels.Update(this);
            await db.SaveChangesAsync();

            NotifyClientsChange();
        }
示例#24
0
 public async Task <ChannelPermissionsNode> GetChannelNodeAsync(PlanetChatChannel channel)
 {
     using (ValourDB Context = new ValourDB(ValourDB.DBOptions))
     {
         return(await Context.ChannelPermissionsNodes.FirstOrDefaultAsync(x => x.Channel_Id == channel.Id &&
                                                                          x.Role_Id == Id));
     }
 }
示例#25
0
 /// <summary>
 /// Returns the primary channel for the planet
 /// </summary>
 public async Task <PlanetChatChannel> GetPrimaryChannelAsync()
 {
     using (ValourDB db = new ValourDB(ValourDB.DBOptions))
     {
         // TODO: Make a way to choose a primary channel rather than just grabbing the first one
         return(await db.PlanetChatChannels.Where(x => x.Planet_Id == this.Id).FirstAsync());
     }
 }
示例#26
0
    private static async Task CreateInvite(HttpContext ctx, ValourDB db, [FromHeader] string authorization)
    {
        var authToken = await ServerAuthToken.TryAuthorize(authorization, db);

        if (authToken == null)
        {
            await TokenInvalid(ctx); return;
        }

        ServerPlanetInvite in_invite = await JsonSerializer.DeserializeAsync <ServerPlanetInvite>(ctx.Request.Body);

        ServerPlanetMember member = await db.PlanetMembers.Include(x => x.Planet).FirstOrDefaultAsync(x => x.Planet_Id == in_invite.Planet_Id && x.User_Id == authToken.User_Id);

        if (member == null)
        {
            await Unauthorized("Member not found", ctx); return;
        }

        if (!await member.HasPermissionAsync(PlanetPermissions.Invite, db))
        {
            await Unauthorized("Member lacks PlanetPermissions.Invite", ctx);

            return;
        }

        // Ensure important fields are correct
        in_invite.Issuer_Id = authToken.User_Id;
        in_invite.Time      = DateTime.UtcNow;
        in_invite.Id        = IdManager.Generate();

        Random random = new();

        const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        string       code  = "";

        bool exists = false;

        do
        {
            code   = new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray());
            exists = await db.PlanetInvites.AnyAsync(x => x.Code == code);
        }while (!exists);

        in_invite.Code = code;

        if (in_invite.Hours < 1)
        {
            in_invite.Hours = null;
        }

        await db.PlanetInvites.AddAsync(in_invite);

        await db.SaveChangesAsync();

        ctx.Response.StatusCode = 201;
        await ctx.Response.WriteAsync(in_invite.Code);
    }
示例#27
0
        /// <summary>
        /// Retrieves a ServerPlanet for the given id
        /// </summary>
        public static async Task <ServerPlanet> FindAsync(ulong id, IMapper mapper)
        {
            using (ValourDB db = new ValourDB(ValourDB.DBOptions))
            {
                Planet planet = await db.Planets.FindAsync(id);

                return(ServerPlanet.FromBase(planet, mapper));
            }
        }
示例#28
0
        public async Task <PermissionState> GetPermissionStateAsync(Permission permission, ulong channel_id)
        {
            using (ValourDB Context = new ValourDB(ValourDB.DBOptions))
            {
                ChannelPermissionsNode node = await Context.ChannelPermissionsNodes.FirstOrDefaultAsync(x => x.Role_Id == Id && x.Channel_Id == channel_id);

                return(node.GetPermissionState(permission));
            }
        }
示例#29
0
        /// <summary>
        /// Retrieves a ServerPlanetChatChannel for the given id
        /// </summary>
        public static async Task <ServerPlanetChatChannel> FindAsync(ulong id)
        {
            using (ValourDB db = new ValourDB(ValourDB.DBOptions))
            {
                PlanetChatChannel channel = await db.PlanetChatChannels.FindAsync(id);

                return(ServerPlanetChatChannel.FromBase(channel));
            }
        }
示例#30
0
        /// <summary>
        /// Returns the member's primary role
        /// </summary>
        public async Task <ServerPlanetRole> GetPrimaryRoleAsync(ValourDB db = null)
        {
            if (RoleMembership == null)
            {
                await LoadRoleMembershipAsync(db);
            }

            return(RoleMembership.FirstOrDefault().Role);
        }