/// <summary> /// Sets the reasons of the given ban. /// </summary> /// <param name="ban">The ban.</param> /// <param name="reason">The reason.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <Result> SetBanReasonAsync ( UserBan ban, string reason, CancellationToken ct = default ) { reason = reason.Trim(); if (reason.IsNullOrWhitespace()) { return(new UserError("You must provide some reason for the ban.")); } if (reason.Length > 1024) { return(new UserError ( "The ban is too long. It can be at most 1024 characters." )); } if (ban.Reason == reason) { return(new UserError("That's already the ban's reason.")); } ban.Reason = reason; ban.NotifyUpdate(); await _database.SaveChangesAsync(ct); return(Result.FromSuccess()); }
/// <summary> /// Posts a notification that a user was banned. /// </summary> /// <param name="ban">The ban.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task NotifyUserBanned(UserBan ban) { var guild = _client.GetGuild((ulong)ban.Server.DiscordID); var getChannel = await GetModerationLogChannelAsync(guild); if (!getChannel.IsSuccess) { return; } var channel = getChannel.Entity; var author = guild.GetUser((ulong)ban.Author.DiscordID); var eb = _feedback.CreateEmbedBase(); eb.WithTitle($"User Banned (#{ban.ID})"); eb.WithColor(Color.Red); var bannedUser = guild.GetUser((ulong)ban.User.DiscordID); eb.WithDescription ( $"{bannedUser.Mention} (ID {bannedUser.Id}) was banned by {author.Mention}.\n" + $"Reason: {ban.Reason}" ); await _feedback.SendEmbedAsync(channel, eb.Build()); }
public void AutoMapper_ConvertFrom_UserBan_To_NewBan_IsValid() { var mapper = Configuration.CreateMapper(); var sourceObject = new UserBan("testChannel", "testUserName", "testReason", "", "111111"); var resultObject = mapper.Map <NewBan>(sourceObject); var expectedObject = new NewBan() { Channel = "testChannel", Reason = "testReason", BanType = Shared.Database.Models.BanType.Ban, BannedTime = DateTime.UtcNow, User = new User { UserId = 111111, UserName = "******", }, }; resultObject.Should().BeEquivalentTo(expectedObject, options => options .Using <DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromMilliseconds(100))) .WhenTypeIs <DateTime>() ); }
/// <summary> /// Posts a notification that a user was banned. /// </summary> /// <param name="ban">The ban.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task <Result> NotifyUserBannedAsync(UserBan ban) { var getChannel = await GetModerationLogChannelAsync(ban.Server.DiscordID); if (!getChannel.IsSuccess) { return(Result.FromError(getChannel)); } var channel = getChannel.Entity; var eb = new Embed { Colour = _feedback.Theme.FaultOrDanger, Title = $"User Banned (#{ban.ID})", Description = $"<@{ban.User.DiscordID}> (ID {ban.User.DiscordID}) was banned by " + $"<@{ban.Author.DiscordID}>.\n" + $"Reason: {ban.Reason}" }; var sendResult = await _feedback.SendEmbedAsync(channel, eb); return(sendResult.IsSuccess ? Result.FromSuccess() : Result.FromError(sendResult)); }
/// <summary> /// Sets the reasons of the given ban. /// </summary> /// <param name="ban">The ban.</param> /// <param name="reason">The reason.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> SetBanReasonAsync(UserBan ban, string reason) { if (reason.IsNullOrWhitespace()) { return(ModifyEntityResult.FromError("You must provide some reason for the ban.")); } if (reason.Length > 1024) { return(ModifyEntityResult.FromError ( "The ban is too long. It can be at most 1024 characters." )); } if (ban.Reason == reason) { return(ModifyEntityResult.FromError("That's already the ban's reason.")); } ban.Reason = reason; ban.NotifyUpdate(); await _database.SaveChangesAsync(); return(ModifyEntityResult.FromSuccess()); }
/// <summary> /// Posts a notification that a user was unbanned. /// </summary> /// <param name="ban">The ban.</param> /// <param name="rescinder">The person who rescinded the ban.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task NotifyUserUnbanned(UserBan ban, IGuildUser rescinder) { var guild = _client.GetGuild((ulong)ban.Server.DiscordID); var getChannel = await GetModerationLogChannelAsync(guild); if (!getChannel.IsSuccess) { return; } var channel = getChannel.Entity; var eb = _feedback.CreateEmbedBase(); eb.WithTitle($"User Unbanned (#{ban.ID})"); eb.WithColor(Color.Green); var whoDidIt = rescinder.IsMe(_client) ? "(expired)" : $"by {rescinder.Mention}"; var bannedUser = guild.GetUser((ulong)ban.User.DiscordID); eb.WithDescription($"{bannedUser.Mention} (ID {bannedUser.Id}) was unbanned {whoDidIt}."); await _feedback.SendEmbedAsync(channel, eb.Build()); }
public async Task <IActionResult> CommentNotification([FromBody] string content, int postId, CancellationToken ct = default) { FeedPost post = await _feedService.GetByIdAsync(postId, ct); if (post == null) { return(BadRequest()); } UserBan globalBan = await _userService.GetFirstBanOfTypeIfAnyAsnc(post.PosterUUID, 1, ct); UserBan feedBan = await _userService.GetFirstBanOfTypeIfAnyAsnc(post.PosterUUID, 3, ct); if (globalBan != null || feedBan != null) { return(Ok()); } Notification notification = Notification.CreateNotification(new APSAlert { body = content }, feedPostId: postId); ICollection <string> tokens = await _userService.GetAPNSFromUUIDAsync(post.PosterUUID); foreach (string token in tokens) { await _userService.PostNotification(token, notification); } return(Ok()); }
private async Task ReturnsUnsuccessfulIfBanDoesNotExist() { var ban = new UserBan(new Server(0), new User(0), new User(1), "Dummy thicc"); var result = await this.Bans.DeleteBanAsync(ban); Assert.False(result.IsSuccess); }
public async Task <UserBan> BanUserAsync(UserBan ban, CancellationToken ct = default) { await _context.UserBans.AddAsync(ban, ct); await _context.SaveChangesAsync(ct); return(ban); }
public TimeSpan GetBanTime(UserBan userBan) { var startBanTime = userBan.StartBanTime; var timeNow = DateTime.Now; var banTime = timeNow - startBanTime; return(banTime); }
public async Task RevokeBanAsync(int userBanId, CancellationToken ct = default) { UserBan ban = await _context.UserBans.FindAsync(userBanId); if (ban != null) { ban.BanExpires = DateTime.UtcNow.AddHours(-3); _context.Update(ban); await _context.SaveChangesAsync(ct); } }
private BanRecord BanToBanRecord(UserBan ban) { return(new BanRecord() { Channel = this.opChannel.Name, Mask = ban.Mask, FromUser = ban.From, Date = ban.Date, Type = ban.Type, }); }
private async Task <OperationResult> RescindBanIfExpiredAsync ( ChannelLoggingService loggingService, BanService bans, SocketGuild guild, UserBan ban, CancellationToken ct ) { if (ct.IsCancellationRequested) { return(OperationResult.FromError("Operation was cancelled.")); } if (!(ban.ExpiresOn <= DateTime.UtcNow)) { // No rescinding is needed, so we'll just bail out return(OperationResult.FromSuccess()); } var rescinder = guild.GetUser(this.Client.CurrentUser.Id); var notifyResult = await loggingService.NotifyUserUnbannedAsync(ban, rescinder); if (!notifyResult.IsSuccess) { return(OperationResult.FromError(notifyResult)); } var deleteResult = await bans.DeleteBanAsync(ban, ct); if (!deleteResult.IsSuccess) { return(OperationResult.FromError(deleteResult)); } try { await guild.RemoveBanAsync((ulong)ban.User.DiscordID); } catch (HttpException hex) when(hex.HttpCode == HttpStatusCode.NotFound) { // Already unbanned return(OperationResult.FromSuccess()); } catch (Exception ex) { return(OperationResult.FromError(ex)); } return(OperationResult.FromSuccess()); }
/// <summary> /// Deletes the given ban. /// </summary> /// <param name="ban">The ban to delete.</param> /// <returns>A deletion result which may or may ban have succeeded.</returns> public async Task <DeleteEntityResult> DeleteBanAsync(UserBan ban) { if (!_database.UserBans.Any(n => n.ID == ban.ID)) { return(DeleteEntityResult.FromError ( "That ban isn't in the database. This is probably an error in the bot." )); } _database.UserBans.Remove(ban); await _database.SaveChangesAsync(); return(DeleteEntityResult.FromSuccess()); }
/// <summary> /// Sets the contextually relevant message for the ban. /// </summary> /// <param name="ban">The ban.</param> /// <param name="messageID">The message.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> SetBanContextMessageAsync ( UserBan ban, long messageID ) { if (ban.MessageID == messageID) { return(ModifyEntityResult.FromError("That's already the ban's context message.")); } ban.MessageID = messageID; ban.NotifyUpdate(); await _database.SaveChangesAsync(); return(ModifyEntityResult.FromSuccess()); }
public async Task <string> CreateAuthTokenForUserAsync(string userUUID) { User user = await _context.Users.FindAsync(userUUID); if (user == null) { return(null); } UserBan chatBan = await _userService.GetFirstBanOfTypeIfAnyAsnc(userUUID, 2); UserBan feedBan = await _userService.GetFirstBanOfTypeIfAnyAsnc(userUUID, 3); JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); byte[] secretKey = Encoding.ASCII.GetBytes(_apiSettings.Secret); List <Claim> claims = new List <Claim> { new Claim(ClaimTypes.Name, userUUID) }; claims.Add(new Claim(ClaimTypes.Role, user.UserIsAdmin ? "admin" : user.UserIsStaff ? "staff" : "user")); if (chatBan == null) { claims.Add(new Claim(ClaimTypes.UserData, "chatAllowed")); } if (feedBan == null) { claims.Add(new Claim(ClaimTypes.UserData, "feedAllowed")); } SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims.ToArray()), Expires = DateTime.Now.AddMinutes(20), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secretKey), SecurityAlgorithms.HmacSha256Signature), Issuer = _apiSettings.Issuer, Audience = _apiSettings.Issuer, IssuedAt = DateTime.UtcNow, NotBefore = DateTime.UtcNow }; SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); return(tokenHandler.WriteToken(token)); }
/// <summary> /// Deletes the given ban. /// </summary> /// <param name="ban">The ban to delete.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A deletion result which may or may ban have succeeded.</returns> public async Task <Result> DeleteBanAsync ( UserBan ban, CancellationToken ct = default ) { if (!_database.UserBans.Any(n => n.ID == ban.ID)) { return(new UserError ( "That ban isn't in the database. This is probably an error in the bot." )); } _database.UserBans.Remove(ban); await _database.SaveChangesAsync(ct); return(Result.FromSuccess()); }
/// <summary> /// Sets the contextually relevant message for the ban. /// </summary> /// <param name="ban">The ban.</param> /// <param name="messageID">The message.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <Result> SetBanContextMessageAsync ( UserBan ban, Snowflake messageID, CancellationToken ct = default ) { if (ban.MessageID == messageID) { return(new UserError("That's already the ban's context message.")); } ban.MessageID = messageID; ban.NotifyUpdate(); await _database.SaveChangesAsync(ct); return(Result.FromSuccess()); }
public async Task PostNotificationToChat(string chatUUID, string senderUUID, string content, CancellationToken ct = default) { User sender = await _userService.GetByIdAsync(senderUUID, ct); if (sender == null) { return; } ICollection <ChatMember> members = await GetMembersForChatAsync(chatUUID, ct); bool isGroupChat = members.Count > 2; string notificationTitle = isGroupChat ? await GetChatNameAsync(chatUUID) : members.FirstOrDefault(cm => cm.UserUUID == senderUUID).UserDTO.UserFullName; foreach (ChatMember member in members.Where(u => u.UserUUID != senderUUID)) { UserBan globalBan = await _userService.GetFirstBanOfTypeIfAnyAsnc(member.UserUUID, 1, ct); UserBan chatBan = await _userService.GetFirstBanOfTypeIfAnyAsnc(member.UserUUID, 2, ct); if (globalBan != null || chatBan != null) { return; } ICollection <string> userAPNSTokens = await _userService.GetAPNSFromUUIDAsync(member.UserUUID, ct); foreach (string token in userAPNSTokens) { Notification notification = Notification.CreateNotification( new APSAlert { title = notificationTitle, subtitle = isGroupChat ? $"From: {members.FirstOrDefault(cm => cm.UserUUID == senderUUID).UserDTO.UserFullName}" : string.Empty, body = content }, chatUUID: chatUUID); await _userService.PostNotification(token, notification); } } }
public void BanUser(UserInfo user, int hours, string reason) { var session = ClientManager.GetByInfo(user); UserBan ban = new UserBan() { User = user, IP = user.LastIp, ExpiresAt = DateTime.Now.AddHours(hours), Reason = reason }; if (session != null) { ban.IP = session.Session.RemoteAddress; ban.MachineId = session.MachineId; ClientManager.Disconnect(session, T._("Banned")); } user.Bans.Add(ban); UserRepository.Save(user); }
/// <summary> /// Sets the date and time at which the ban expires. /// </summary> /// <param name="ban">The ban.</param> /// <param name="expiresOn">The date and time at which the ban expires.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> SetBanExpiryDateAsync ( UserBan ban, DateTime expiresOn ) { if (ban.ExpiresOn == expiresOn) { return(ModifyEntityResult.FromError("That's already the ban's expiry date.")); } if (expiresOn < DateTime.UtcNow) { return(ModifyEntityResult.FromError("Bans can't expire in the past.")); } ban.ExpiresOn = expiresOn; ban.NotifyUpdate(); await _database.SaveChangesAsync(); return(ModifyEntityResult.FromSuccess()); }
/// <summary> /// Sets the date and time at which the ban expires. /// </summary> /// <param name="ban">The ban.</param> /// <param name="expiresOn">The date and time at which the ban expires.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <Result> SetBanExpiryDateAsync ( UserBan ban, DateTimeOffset expiresOn, CancellationToken ct = default ) { if (ban.ExpiresOn == expiresOn) { return(new UserError("That's already the ban's expiry date.")); } if (expiresOn < DateTimeOffset.UtcNow) { return(new UserError("Bans can't expire in the past.")); } ban.ExpiresOn = expiresOn; ban.NotifyUpdate(); await _database.SaveChangesAsync(ct); return(Result.FromSuccess()); }
/// <summary> /// Posts a notification that a user was unbanned. /// </summary> /// <param name="ban">The ban.</param> /// <param name="rescinderID">The person who rescinded the ban.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task <Result> NotifyUserUnbannedAsync(UserBan ban, Snowflake rescinderID) { var getChannel = await GetModerationLogChannelAsync(ban.Server.DiscordID); if (!getChannel.IsSuccess) { return(Result.FromError(getChannel)); } var getSelf = await _userAPI.GetCurrentUserAsync(); if (!getSelf.IsSuccess) { return(Result.FromError(getSelf)); } var self = getSelf.Entity; var channel = getChannel.Entity; var whoDidIt = rescinderID == self.ID ? "(expired)" : $"by <@{rescinderID}>"; var eb = new Embed { Colour = _feedback.Theme.Success, Title = $"User Unbanned (#{ban.ID})", Description = $"<@{ban.User.DiscordID}> (ID {ban.User.DiscordID}) was unbanned {whoDidIt}." }; var sendResult = await _feedback.SendEmbedAsync(channel, eb); return(sendResult.IsSuccess ? Result.FromSuccess() : Result.FromError(sendResult)); }
public async Task <IActionResult> BanUser([FromBody] UserBan ban, CancellationToken ct = default) { Console.WriteLine($"LOG: User {ban.UserUUID} banned by {ban.BannedByUUID}"); return(Ok(await _userService.BanUserAsync(ban, ct))); }
/// <summary> /// Creates a ban for the given user. /// </summary> /// <param name="authorUser">The author of the ban.</param> /// <param name="guildUser">The user.</param> /// <param name="reason">The reason of the ban.</param> /// <param name="messageID">The message that caused the ban, if any.</param> /// <param name="expiresOn">The expiry date for the ban, if any.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserBan> > CreateBanAsync ( IUser authorUser, IGuildUser guildUser, string reason, long?messageID = null, DateTime?expiresOn = null ) { var getServer = await _servers.GetOrRegisterServerAsync(guildUser.Guild); if (!getServer.IsSuccess) { return(CreateEntityResult <UserBan> .FromError(getServer)); } var server = getServer.Entity; var getUser = await _users.GetOrRegisterUserAsync(guildUser); if (!getUser.IsSuccess) { return(CreateEntityResult <UserBan> .FromError(getUser)); } var user = getUser.Entity; var getAuthor = await _users.GetOrRegisterUserAsync(authorUser); if (!getAuthor.IsSuccess) { return(CreateEntityResult <UserBan> .FromError(getAuthor)); } var author = getAuthor.Entity; var ban = new UserBan(server, user, author, string.Empty); var setReason = await SetBanReasonAsync(ban, reason); if (!setReason.IsSuccess) { return(CreateEntityResult <UserBan> .FromError(setReason)); } if (!(messageID is null)) { var setMessage = await SetBanContextMessageAsync(ban, messageID.Value); if (!setMessage.IsSuccess) { return(CreateEntityResult <UserBan> .FromError(setMessage)); } } if (!(expiresOn is null)) { var setExpiry = await SetBanExpiryDateAsync(ban, expiresOn.Value); if (!setExpiry.IsSuccess) { return(CreateEntityResult <UserBan> .FromError(setExpiry)); } } _database.UserBans.Update(ban); await _database.SaveChangesAsync(); // Requery the database var getBan = await GetBanAsync(guildUser.Guild, ban.ID); if (!getBan.IsSuccess) { return(CreateEntityResult <UserBan> .FromError(getBan)); } return(CreateEntityResult <UserBan> .FromSuccess(getBan.Entity)); }