public async Task <TaskResult> SetDescription(string description, 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.")); } PlanetChatChannel channel = await Context.PlanetChatChannels.Where(x => x.Id == id).FirstOrDefaultAsync(); ServerPlanet planet = await ServerPlanet.FindAsync(channel.Planet_Id, Mapper); if (!(await planet.AuthorizedAsync(authToken, PlanetPermissions.ManageChannels))) { return(new TaskResult(false, "You are not authorized to do this.")); } channel.Description = description; await Context.SaveChangesAsync(); return(new TaskResult(true, "Successfully set description.")); }
public async Task <TaskResult> SetName(string name, 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.")); } 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.")); } category.Name = name; await Context.SaveChangesAsync(); await PlanetHub.Current.Clients.Group($"p-{category.Planet_Id}").SendAsync("RefreshChannelList", ""); return(new TaskResult(true, "Successfully set name.")); }
public async Task <TaskResult> KickUser(ulong id, ulong Planet_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.")); } PlanetMember member = await Context.PlanetMembers.Where(x => x.User_Id == id && x.Planet_Id == Planet_Id).FirstOrDefaultAsync(); if (member == null) { return(new TaskResult(true, $"Could not find PlanetMember {id}")); } Context.PlanetMembers.Remove(member); await Context.SaveChangesAsync(); return(new TaskResult(true, $"Successfully kicked user {id}")); }
public async Task <TaskResult> Join(string code, 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, $"Incorrect token!")); } PlanetInvite invite = await Context.PlanetInvites.FindAsync(code); if (invite == null) { return(new TaskResult(false, $"Code is not found!")); } PlanetBan ban = await Context.PlanetBans.FirstOrDefaultAsync(x => x.User_Id == userid && x.Planet_Id == invite.Planet_Id); if (ban != null) { return(new TaskResult(false, $"User is banned from this planet!")); } PlanetMember mem = await Context.PlanetMembers.FirstOrDefaultAsync(x => x.User_Id == userid && x.Planet_Id == invite.Planet_Id); if (mem != null) { return(new TaskResult(false, $"User is already in this planet!")); } Planet planet = await Context.Planets.FirstOrDefaultAsync(x => x.Id == invite.Planet_Id); if (!planet.Public) { return(new TaskResult(false, $"Planet is set to private!")); } PlanetMember member = new PlanetMember() { User_Id = userid, Planet_Id = invite.Planet_Id, }; await Context.PlanetMembers.AddAsync(member); await Context.SaveChangesAsync(); return(new TaskResult(true, $"Joined Planet")); }
private static async Task PasswordReset(HttpContext ctx, ValourDB db, [FromBody] string email) { UserEmail userEmail = await db.UserEmails.FindAsync(email.ToLower()); if (userEmail == null) { await NotFound("No account found for email", ctx); return; } // If a recovery already exists for this user, remove it var old = db.PasswordRecoveries.Where(x => x.User_Id == userEmail.User_Id); if (old.Count() > 0) { db.PasswordRecoveries.RemoveRange(old); await db.SaveChangesAsync(); } string recoveryCode = Guid.NewGuid().ToString(); PasswordRecovery recovery = new PasswordRecovery() { Code = recoveryCode, User_Id = userEmail.User_Id }; await db.PasswordRecoveries.AddAsync(recovery); await db.SaveChangesAsync(); // Send registration email string emsg = $@"<body> <h2 style='font-family:Helvetica;'> Valour Password Recovery </h2> <p style='font-family:Helvetica;> If you did not request this email, please ignore it. To reset your password, please use the following link: </p> <p style='font-family:Helvetica;'> <a href='https://valour.gg/RecoverPassword/{recoveryCode}'>Click here to recover</a> </p> </body>"; string rawmsg = $"To reset your password, please go to the following link:\nhttps://valour.gg/RecoverPassword/{recoveryCode}"; await EmailManager.SendEmailAsync(email, "Valour Password Recovery", rawmsg, emsg); Console.WriteLine($"Sent recovery email to {email}"); ctx.Response.StatusCode = 200; await ctx.Response.WriteAsync("Email sent"); }
/// <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})"); }
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); } }
/// <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(); }
/// <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(); }
/// <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(); }
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); }
/// <summary> /// Tries to set the planet description /// </summary> public async Task <TaskResult> TrySetDescriptionAsync(string desc, ValourDB db) { this.Description = desc; db.Planets.Update(this); await db.SaveChangesAsync(); NotifyClientsChange(); return(new TaskResult(true, "Success")); }
/// <summary> /// Tries to set the planet open state /// </summary> public async Task <TaskResult> TrySetPublicAsync(bool pub, ValourDB db) { this.Public = pub; db.Planets.Update(this); await db.SaveChangesAsync(); NotifyClientsChange(); return(new TaskResult(true, "Success")); }
/// <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 userid, ulong planetid, 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)); } // User is verified and given channel info is valid by this point // Creates the channel channel PlanetChatChannel channel = new PlanetChatChannel() { Name = name, Planet_Id = planetid, Message_Count = 0 }; // Add channel to database await Context.PlanetChatChannels.AddAsync(channel); // Save changes to DB await Context.SaveChangesAsync(); // Return success return(new TaskResult <ulong>(true, "Successfully created channel.", channel.Id)); }
/// <summary> /// Allows a token to be requested using basic login information /// </summary> public async Task <TokenResponse> RequestStandardToken(string email, string password) { var result = await UserManager.ValidateAsync(CredentialType.PASSWORD, email, password); // If the verification failed, forward the failure if (!result.Result.Success) { return(new TokenResponse(null, result.Result)); } // Otherwise, get the user we just verified User user = result.User; if (!user.Verified_Email) { EmailConfirmCode confirmCode = await Context.EmailConfirmCodes.FindAsync(password); // Someone using another person's verification is a little // worrying, and we don't want them to know it worked, so we'll // send the same error either way. if (confirmCode == null || confirmCode.User_Id != user.Id) { return(new TokenResponse(null, new TaskResult(false, "The email associated with this account needs to be verified! Please log in using the code " + "that was emailed as your password."))); } // At this point the email has been confirmed user.Verified_Email = true; Context.EmailConfirmCodes.Remove(confirmCode); await Context.SaveChangesAsync(); } // We now have to create a token for the user AuthToken token = new AuthToken() { App_Id = "VALOUR", Id = Guid.NewGuid().ToString(), Time = DateTime.UtcNow, Expires = DateTime.UtcNow.AddDays(7), Scope = Permission.FullControl.Value, User_Id = user.Id }; using (ValourDB context = new ValourDB(ValourDB.DBOptions)) { await context.AuthTokens.AddAsync(token); await context.SaveChangesAsync(); } return(new TokenResponse(token.Id, new TaskResult(true, "Successfully verified and retrieved token!"))); }
public async Task <LocalRedirectResult> Join(string code, 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 LocalRedirectResult("/")); } PlanetInvite invite = await Context.PlanetInvites.Where(x => x.Code == code).FirstOrDefaultAsync(); if (invite == null) { return(new LocalRedirectResult("/")); } PlanetMember mem = await Context.PlanetMembers.Where(x => x.User_Id == userid && x.Planet_Id == invite.Planet_Id).FirstOrDefaultAsync(); if (mem != null) { return(new LocalRedirectResult("/")); } PlanetMember member = new PlanetMember() { User_Id = userid, Planet_Id = invite.Planet_Id, }; await Context.PlanetMembers.AddAsync(member); await Context.SaveChangesAsync(); return(new LocalRedirectResult("/")); }
public async Task <TaskResult <PlanetInvite> > GetInvite(string code, ulong user_id) { PlanetInvite invite = await Context.PlanetInvites.FirstOrDefaultAsync(x => x.Code == code); if (invite.IsPermanent() == false) { if (DateTime.UtcNow > invite.Time.AddMinutes((double)invite.Hours)) { Context.PlanetInvites.Remove(invite); await Context.SaveChangesAsync(); return(new TaskResult <PlanetInvite>(false, $"Invite is expired", null)); } } PlanetBan ban = await Context.PlanetBans.FirstOrDefaultAsync(x => x.User_Id == user_id && x.Planet_Id == invite.Planet_Id); if (ban != null) { return(new TaskResult <PlanetInvite>(false, $"User is banned from this planet!", null)); } PlanetMember member = await Context.PlanetMembers.FirstOrDefaultAsync(x => x.User_Id == user_id && x.Planet_Id == invite.Planet_Id); if (member != null) { return(new TaskResult <PlanetInvite>(false, $"User is already in this planet!", null)); } Planet planet = await Context.Planets.FirstOrDefaultAsync(x => x.Id == invite.Planet_Id); if (!planet.Public) { return(new TaskResult <PlanetInvite>(false, $"Planet is set to private!", null)); } return(new TaskResult <PlanetInvite>(true, $"Successfully got invite", invite)); }
/// <summary> /// Tries to delete this role /// </summary> public async Task <TaskResult <int> > TryDeleteAsync(ServerPlanetMember member, ValourDB db) { if (member == null) { return(new TaskResult <int>(false, "Member not found", 404)); } if (member.Planet_Id != Planet_Id) { return(new TaskResult <int>(false, "Member is of another planet", 403)); } if (!await member.HasPermissionAsync(PlanetPermissions.ManageRoles, db)) { return(new TaskResult <int>(false, "Member lacks PlanetPermissions.ManageRoles", 403)); } if (await member.GetAuthorityAsync() <= GetAuthority()) { return(new TaskResult <int>(false, "Member authority is lower than role authority", 403)); } Planet ??= await db.Planets.FindAsync(Planet_Id); if (Id == Planet.Default_Role_Id) { return(new TaskResult <int>(false, "Cannot remove default role", 400)); } // Remove all members var members = db.PlanetRoleMembers.Where(x => x.Role_Id == Id); db.PlanetRoleMembers.RemoveRange(members); // Remove role nodes var channelNodes = db.ChatChannelPermissionsNodes.Where(x => x.Role_Id == Id); var categoryNodes = db.CategoryPermissionsNodes.Where(x => x.Role_Id == Id); db.ChatChannelPermissionsNodes.RemoveRange(channelNodes); db.CategoryPermissionsNodes.RemoveRange(categoryNodes); // Remove self db.PlanetRoles.Remove(this); await db.SaveChangesAsync(); // Notify clients PlanetHub.NotifyRoleDeletion(this); return(new TaskResult <int>(true, "Removed role", 200)); }
private static async Task RecoverPassword(HttpContext ctx, ValourDB db, [FromBody] PasswordRecoveryRequest request) { if (request == null) { await BadRequest("Include request data in body", ctx); return; } PasswordRecovery recovery = await db.PasswordRecoveries.FindAsync(request.Code); if (recovery == null) { await NotFound("Recovery request not found", ctx); return; } TaskResult passwordValid = User.TestPasswordComplexity(request.Password); if (!passwordValid.Success) { await BadRequest(passwordValid.Message, ctx); return; } // Get user's old credentials Credential credential = await db.Credentials.FirstOrDefaultAsync(x => x.User_Id == recovery.User_Id && x.Credential_Type == CredentialType.PASSWORD); if (credential == null) { await NotFound("No password-type credentials found. Do you log in via third party service?", ctx); return; } // Remove recovery code db.PasswordRecoveries.Remove(recovery); // Modify old credentials // Generate salt byte[] salt = new byte[32]; PasswordManager.GenerateSalt(salt); // Generate password hash byte[] hash = PasswordManager.GetHashForPassword(request.Password, salt); credential.Salt = salt; credential.Secret = hash; db.Credentials.Update(credential); await db.SaveChangesAsync(); ctx.Response.StatusCode = 200; await ctx.Response.WriteAsync("Success"); }
public async Task <TaskResult <int> > TryKickMemberAsync(ServerPlanetMember member, ServerPlanetMember target, ValourDB db) { if (member == null) { return(new TaskResult <int>(false, "Member not found", 404)); } if (!await HasPermissionAsync(member, PlanetPermissions.Kick, db)) { return(new TaskResult <int>(false, "Member lacks PlanetPermissions.View", 403)); } if (target == null) { return(new TaskResult <int>(false, $"Target not found", 404)); } if (member.Id == target.Id) { return(new TaskResult <int>(false, "You cannot kick yourself!", 400)); } if (!await HasPermissionAsync(member, PlanetPermissions.Kick, db)) { return(new TaskResult <int>(false, "Member lacks PlanetPermissions.Kick", 403)); } if (await member.GetAuthorityAsync() <= await target.GetAuthorityAsync()) { return(new TaskResult <int>(false, "You can only kick members with lower authority!", 403)); } // Remove roles var roles = db.PlanetRoleMembers.Where(x => x.Member_Id == target.Id); foreach (ServerPlanetRoleMember role in roles) { db.PlanetRoleMembers.Remove(role); } // Remove member db.PlanetMembers.Remove(target); // Save changes await db.SaveChangesAsync(); return(new TaskResult <int>(true, $"Successfully kicked user", 200)); }
private static async Task LogOut(HttpContext ctx, ValourDB db, [FromHeader] string authorization) { var authToken = await ServerAuthToken.TryAuthorize(authorization, db); if (authToken == null) { await Unauthorized("Include token", ctx); return; } db.AuthTokens.Remove(authToken); await db.SaveChangesAsync(); ctx.Response.StatusCode = 200; await ctx.Response.WriteAsync("Success"); }
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}")); }
/// <summary> /// Deletes this channel /// </summary> public async Task <TaskResult <int> > TryDeleteAsync(ServerPlanetMember member, ValourDB db) { Planet ??= await GetPlanetAsync(db); if (Id == Planet.Main_Channel_Id) { return(new TaskResult <int>(false, $"Cannot delete main channel", 400)); } if (member == null) { return(new TaskResult <int>(false, "Member not found", 403)); } if (!await HasPermission(member, ChatChannelPermissions.View, db)) { return(new TaskResult <int>(false, "Member lacks ChatChannelPermissions.View", 403)); } if (!await HasPermission(member, ChatChannelPermissions.ManageChannel, db)) { return(new TaskResult <int>(false, "Member lacks ChatChannelPermissions.ManageChannel", 403)); } // Remove permission nodes db.ChatChannelPermissionsNodes.RemoveRange( db.ChatChannelPermissionsNodes.Where(x => x.Channel_Id == Id) ); // Remove messages db.PlanetMessages.RemoveRange( db.PlanetMessages.Where(x => x.Channel_Id == Id) ); // Remove channel db.PlanetChatChannels.Remove( await db.PlanetChatChannels.FirstOrDefaultAsync(x => x.Id == Id) ); // Save changes await db.SaveChangesAsync(); // Notify channel deletion await PlanetHub.NotifyChatChannelDeletion(this); return(new TaskResult <int>(true, "Success", 200)); }
/// <summary> /// Sets the name of this channel /// </summary> public async Task <TaskResult> TrySetNameAsync(string name, ValourDB db) { TaskResult validName = ValidateName(name); if (!validName.Success) { return(validName); } this.Name = name; db.PlanetChatChannels.Update(this); await db.SaveChangesAsync(); NotifyClientsChange(); return(new TaskResult(true, "Success")); }
private static async Task AddRole(HttpContext ctx, ValourDB db, [FromHeader] string authorization) { AuthToken auth = await ServerAuthToken.TryAuthorize(authorization, db); if (auth is null) { await TokenInvalid(ctx); return; } ServerPlanetRole in_role = await JsonSerializer.DeserializeAsync <ServerPlanetRole>(ctx.Response.Body); ServerPlanetMember member = await db.PlanetMembers.FirstOrDefaultAsync(x => x.User_Id == auth.User_Id && x.Planet_Id == in_role.Planet_Id); if (member is null) { await Unauthorized("Member not found", ctx); return; } if (!auth.HasScope(UserPermissions.PlanetManagement)) { await Unauthorized("Auth token lacks UserPermissions.PlanetManagement", ctx); return; } if (!await member.HasPermissionAsync(PlanetPermissions.ManageRoles, db)) { await Unauthorized("Member lacks PlanetPermissions.ManageRoles", ctx); return; } // Ensure fields are correct in_role.Planet_Id = member.Planet_Id; in_role.Position = (uint)await db.PlanetRoles.CountAsync(x => x.Planet_Id == in_role.Planet_Id); // Generate ID in_role.Id = IdManager.Generate(); await db.PlanetRoles.AddAsync(in_role); await db.SaveChangesAsync(); ctx.Response.StatusCode = 201; await ctx.Response.WriteAsJsonAsync(in_role.Id); return; }
private static async Task GetInvite(HttpContext ctx, ValourDB db, string invite_code, [FromHeader] string authorization) { var authToken = await ServerAuthToken.TryAuthorize(authorization, db); if (authToken == null) { await TokenInvalid(ctx); return; } var invite = await db.PlanetInvites.Include(x => x.Planet).FirstOrDefaultAsync(x => x.Code == invite_code); if (invite == null) { await NotFound("Invite code not found", ctx); return; } if (!invite.IsPermanent()) { if (DateTime.UtcNow > invite.Time.AddMinutes((double)(invite.Hours * 60))) { db.PlanetInvites.Remove(invite); await db.SaveChangesAsync(); ctx.Response.StatusCode = 200; await ctx.Response.WriteAsync("Invite is expired"); return; } } var ban = await db.PlanetBans.FirstOrDefaultAsync(x => x.User_Id == authToken.User_Id && x.Planet_Id == invite.Planet_Id); if (ban is not null) { await Unauthorized("User is banned", ctx); return; } if (!invite.Planet.Public) { await Unauthorized("Planet is set to private", ctx); return; } ctx.Response.StatusCode = 200; await ctx.Response.WriteAsJsonAsync(invite); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { Task task = Task.Run(async() => { while (true) { try { using (var scope = _scopeFactory.CreateScope()) { ValourDB context = scope.ServiceProvider.GetRequiredService <ValourDB>(); DateTime now = DateTime.UtcNow; foreach (Messaging.CacheMessage message in context.Messages) { if (message.TimeSent.AddHours(24) < now) { context.Messages.Remove(message); } await context.SaveChangesAsync(); } } Console.WriteLine("Checked Message Cache"); Thread.Sleep(1000 * 60 * 60); } catch (System.Exception e) { Console.WriteLine("FATAL MESSAGE CACHE ERROR:"); Console.WriteLine(e.Message); } } }); while (!task.IsCompleted) { _logger.LogInformation("Message Cache Worker running at: {time}", DateTimeOffset.Now); await Task.Delay(60000, stoppingToken); } _logger.LogInformation("Message Cache Worker task stopped at: {time}", DateTimeOffset.Now); _logger.LogInformation("Restarting.", DateTimeOffset.Now); } }
/// <summary> /// Will return the auth object for a valid token, including the user. /// This will log the access time in the user object. /// A null response means the token was invalid. /// </summary> public static async Task <ServerAuthToken> TryAuthorize(string token, ValourDB db) { if (token == null) { return(null); } ServerAuthToken authToken = null; if (QuickCache.ContainsKey(token)) { authToken = QuickCache[token]; } else { authToken = await db.AuthTokens.FindAsync(token); QuickCache.TryAdd(token, authToken); } // Spin off a task to do things we don't want to wait on var t = Task.Run(async() => { using (ValourDB tdb = new ValourDB(ValourDB.DBOptions)) { if (authToken == null) { authToken = await tdb.AuthTokens.FindAsync(token); } if (authToken != null) { ServerUser user = await tdb.Users.FindAsync(authToken.User_Id); user.Last_Active = DateTime.UtcNow; await tdb.SaveChangesAsync(); } } }); return(authToken); }
public async Task <TaskResult <int> > TryUpdateAsync(ServerPlanetMember member, ServerPlanetRole newRole, ValourDB db) { if (member == null) { return(new TaskResult <int>(false, "Member not found", 403)); } if (member.Planet_Id != Planet_Id) { return(new TaskResult <int>(false, "Member is of another planet", 403)); } if (!await member.HasPermissionAsync(PlanetPermissions.ManageRoles, db)) { return(new TaskResult <int>(false, "Member lacks PlanetPermissions.ManageRoles", 403)); } if (await member.GetAuthorityAsync() <= GetAuthority()) { return(new TaskResult <int>(false, "Member authority is lower than role authority", 403)); } if (newRole.Id != Id) { return(new TaskResult <int>(false, "Given role does not match id", 400)); } this.Name = newRole.Name; this.Position = newRole.Position; this.Permissions = newRole.Permissions; this.Color_Red = newRole.Color_Red; this.Color_Green = newRole.Color_Green; this.Color_Blue = newRole.Color_Blue; this.Bold = newRole.Bold; this.Italics = newRole.Italics; db.PlanetRoles.Update(this); await db.SaveChangesAsync(); PlanetHub.NotifyRoleChange(this); return(new TaskResult <int>(true, "Success", 200)); }
/// <summary> /// Tries to delete the category while respecting constraints /// </summary> public async Task <TaskResult> TryDeleteAsync(ValourDB db) { var planet = await GetPlanetAsync(); if (await db.PlanetCategories.CountAsync(x => x.Planet_Id == Planet_Id) < 2) { return(new TaskResult(false, "Last category cannot be deleted")); } var childCategoryCount = await db.PlanetCategories.CountAsync(x => x.Parent_Id == Id); var childChannelCount = await db.PlanetChatChannels.CountAsync(x => x.Parent_Id == Id); if (childCategoryCount != 0 || childChannelCount != 0) { return(new TaskResult(false, "Category must be empty")); } // Remove permission nodes db.CategoryPermissionsNodes.RemoveRange( db.CategoryPermissionsNodes.Where(x => x.Category_Id == Id) ); // Remove category db.PlanetCategories.Remove( await db.PlanetCategories.FindAsync(Id) ); // Save changes await db.SaveChangesAsync(); // Notify of update await PlanetHub.NotifyCategoryDeletion(this); return(new TaskResult(true, "Success")); }