Esempio n. 1
0
    /// <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());
    }
Esempio n. 2
0
        /// <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());
        }
Esempio n. 3
0
        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));
    }
Esempio n. 5
0
        /// <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());
        }
Esempio n. 6
0
        /// <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());
        }
Esempio n. 8
0
            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);
            }
Esempio n. 9
0
        public async Task <UserBan> BanUserAsync(UserBan ban, CancellationToken ct = default)
        {
            await _context.UserBans.AddAsync(ban, ct);

            await _context.SaveChangesAsync(ct);

            return(ban);
        }
Esempio n. 10
0
        public TimeSpan GetBanTime(UserBan userBan)
        {
            var startBanTime = userBan.StartBanTime;
            var timeNow      = DateTime.Now;
            var banTime      = timeNow - startBanTime;

            return(banTime);
        }
Esempio n. 11
0
        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);
            }
        }
Esempio n. 12
0
 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());
        }
Esempio n. 14
0
        /// <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());
        }
Esempio n. 15
0
        /// <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());
        }
Esempio n. 16
0
        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));
        }
Esempio n. 17
0
    /// <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());
    }
Esempio n. 18
0
    /// <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());
    }
Esempio n. 19
0
        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);
                }
            }
        }
Esempio n. 20
0
        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);
        }
Esempio n. 21
0
        /// <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());
        }
Esempio n. 22
0
    /// <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)));
 }
Esempio n. 25
0
        /// <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));
        }