protected GlobalViewDataModel CreateGlobalViewDataAsync(CachedAccount cachedAccount, CommonUserAccountModel commonUserAccountModel = null)
        {
            var globalViewData = Mapper.Map <GlobalViewDataModel>(cachedAccount);

            if (commonUserAccountModel != null)
            {
                globalViewData.Permissions       = commonUserAccountModel.Permissions;
                globalViewData.UserOwnsAnAccount = cachedAccount.OwnerUserId == commonUserAccountModel.UserId;
            }

            return(globalViewData);
        }
Ejemplo n.º 2
0
        public async Task HandleMessageAsync(GuildConfig guild, CachedAccount account, IMessage message, bool doAutoProxy)
        {
            // Bail early if this isn't in a guild channel
            if (!(message.Channel is ITextChannel channel))
            {
                return;
            }

            // Find a member with proxy tags matching the message
            var match = GetProxyTagMatch(message.Content, account.System, account.Members);

            // O(n) lookup since n is small (max ~100 in prod) and we're more constrained by memory (for a dictionary) here
            var systemSettingsForGuild = account.SettingsForGuild(channel.GuildId);

            // If we didn't get a match by proxy tags, try to get one by autoproxy
            // Also try if we *did* get a match, but there's no inner text. This happens if someone sends a message that
            // is equal to someone else's tags, and messages like these should be autoproxied if possible

            // All of this should only be done if this call allows autoproxy.
            // When a normal message is sent, autoproxy is enabled, but if this method is called from a message *edit*
            // event, then autoproxy is disabled. This is so AP doesn't "retrigger" when the original message was escaped.
            if (doAutoProxy && (match == null || (match.InnerText.Trim().Length == 0 && message.Attachments.Count == 0)))
            {
                match = await GetAutoproxyMatch(account, systemSettingsForGuild, message, channel);
            }

            // If we still haven't found any, just yeet
            if (match == null)
            {
                return;
            }

            // And make sure the channel's not blacklisted from proxying.
            if (guild.Blacklist.Contains(channel.Id))
            {
                return;
            }

            // Make sure the system hasn't blacklisted the guild either
            if (!systemSettingsForGuild.ProxyEnabled)
            {
                return;
            }

            // We know message.Channel can only be ITextChannel as PK doesn't work in DMs/groups
            // Afterwards we ensure the bot has the right permissions, otherwise bail early
            if (!await EnsureBotPermissions(channel))
            {
                return;
            }

            // Can't proxy a message with no content and no attachment
            if (match.InnerText.Trim().Length == 0 && message.Attachments.Count == 0)
            {
                return;
            }

            var memberSettingsForGuild = account.SettingsForMemberGuild(match.Member.Id, channel.GuildId);

            // Get variables in order and all
            var proxyName = match.Member.ProxyName(match.System.Tag, memberSettingsForGuild.DisplayName);
            var avatarUrl = memberSettingsForGuild.AvatarUrl ?? match.Member.AvatarUrl ?? match.System.AvatarUrl;

            // If the name's too long (or short), bail
            if (proxyName.Length < 2)
            {
                throw Errors.ProxyNameTooShort(proxyName);
            }
            if (proxyName.Length > Limits.MaxProxyNameLength)
            {
                throw Errors.ProxyNameTooLong(proxyName);
            }

            // Add the proxy tags into the proxied message if that option is enabled
            // Also check if the member has any proxy tags - some cases autoproxy can return a member with no tags
            var messageContents = (match.Member.KeepProxy && match.ProxyTags.HasValue)
                ? $"{match.ProxyTags.Value.Prefix}{match.InnerText}{match.ProxyTags.Value.Suffix}"
                : match.InnerText;

            // Sanitize @everyone, but only if the original user wouldn't have permission to
            messageContents = SanitizeEveryoneMaybe(message, messageContents);

            // Execute the webhook itself
            var hookMessageId = await _webhookExecutor.ExecuteWebhook(
                channel,
                proxyName, avatarUrl,
                messageContents,
                message.Attachments
                );

            // Store the message in the database, and log it in the log channel (if applicable)
            await _data.AddMessage(message.Author.Id, hookMessageId, channel.GuildId, message.Channel.Id, message.Id, match.Member);

            await _logChannel.LogMessage(match.System, match.Member, hookMessageId, message.Id, message.Channel as IGuildChannel, message.Author, match.InnerText, guild);

            // Wait a second or so before deleting the original message
            await Task.Delay(1000);

            try
            {
                await message.DeleteAsync();
            }
            catch (HttpException)
            {
                // If it's already deleted, we just log and swallow the exception
                _logger.Warning("Attempted to delete already deleted proxy trigger message {Message}", message.Id);
            }
        }
Ejemplo n.º 3
0
        private async Task <ProxyMatch> GetAutoproxyMatch(CachedAccount account, SystemGuildSettings guildSettings, IMessage message, IGuildChannel channel)
        {
            // For now we use a backslash as an "escape character", subject to change later
            if ((message.Content ?? "").TrimStart().StartsWith("\\"))
            {
                return(null);
            }

            PKMember member = null;

            // Figure out which member to proxy as
            switch (guildSettings.AutoproxyMode)
            {
            case AutoproxyMode.Off:
                // Autoproxy off, bail
                return(null);

            case AutoproxyMode.Front:
                // Front mode: just use the current first fronter
                member = await _data.GetFirstFronter(account.System);

                break;

            case AutoproxyMode.Latch:
                // Latch mode: find last proxied message, use *that* member
                var msg = await _data.GetLastMessageInGuild(message.Author.Id, channel.GuildId);

                if (msg == null)
                {
                    return(null);                 // No message found
                }
                // If the message is older than 6 hours, ignore it and force the sender to "refresh" a proxy
                // This can be revised in the future, it's a preliminary value.
                var timestamp = SnowflakeUtils.FromSnowflake(msg.Message.Mid).ToInstant();
                var timeSince = SystemClock.Instance.GetCurrentInstant() - timestamp;
                if (timeSince > Duration.FromHours(6))
                {
                    return(null);
                }

                member = msg.Member;
                break;

            case AutoproxyMode.Member:
                // Member mode: just use that member
                // O(n) lookup since n is small (max 1000 de jure) and we're more constrained by memory (for a dictionary) here
                member = account.Members.FirstOrDefault(m => m.Id == guildSettings.AutoproxyMember);
                break;
            }

            // If we haven't found the member (eg. front mode w/ no fronter), bail again
            if (member == null)
            {
                return(null);
            }
            return(new ProxyMatch
            {
                System = account.System,
                Member = member,
                // Autoproxying members with no proxy tags is possible, return the correct result
                ProxyTags = member.ProxyTags.Count > 0 ? member.ProxyTags.First() : (ProxyTag?)null,
                InnerText = message.Content
            });
        }
        public async Task <string> SendEvidencePackage(CachedAccount cachedAccount, long citationNumber, string FTPURl, string FTPFolder, string FTPUsername, string FTPPassword, Citation citationAttachment, string awsAccessKey, string awsSecretKey, string bucketName)
        {
            var result = string.Empty;

            try
            {
                _cachedAccount = cachedAccount;
                // var FilePath = $"c:\\temp";
                //var archivePath = $"c:\\temp\\{AccountNumber}-{citationNumber}.zip";
                //Create folder if not Exists
                var FilePath = Path.Combine(_env.WebRootPath, @"upload");

                var FileLocation = FilePath + @"\CitationReceipt.txt";

                if (!Directory.Exists(FilePath))
                {
                    Directory.CreateDirectory(FilePath);
                }
                else
                {
                    System.IO.DirectoryInfo di = new DirectoryInfo(FilePath);

                    foreach (FileInfo file in di.GetFiles())
                    {
                        file.Delete();
                    }
                }



                var archivePath = $"{FilePath}\\{cachedAccount.Number}-{citationNumber}.zip";

                //Read the file and copy it to the temp directory
                if (citationAttachment.Attachments != null)
                {
                    foreach (var attach in citationAttachment.Attachments)
                    {
                        var cityAppFile = await _fileService.ReadFile(attach.Attachment.Key, awsAccessKey, awsSecretKey, bucketName);

                        if (cityAppFile.FileName != null)
                        {
                            //Download the file to temp path
                            var newFile = $"{FilePath}\\{attach.Attachment.FileName}";
                            using (var fileStream = File.Create(newFile))
                            {
                                cityAppFile.FileStream.Position = 0;
                                cityAppFile.FileStream.CopyTo(fileStream);
                            }
                        }
                    }
                }


                //Create Text file
                await CitationReceipt(citationAttachment, FileLocation, cachedAccount);

                //Zip all attachment
                result = await CreateArchive(FilePath, archivePath, FTPURl, FTPFolder, FTPUsername, FTPPassword);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"Error SendEvidencePackage file To FTP: Exception: {ex}, InnerException: {ex.InnerException} ");

                throw ex;
            }

            return(result);
        }
        public async Task <bool> CitationReceipt(Citation citation, string FileLocation, CachedAccount cachedAccount)
        {
            var commonAccount = await _commonCtx.CommonAccounts
                                .Include(m => m.City)
                                .Where(x => x.Id == citation.AccountId).SingleOrDefaultAsync();

            if (commonAccount == null)
            {
                return(false);
            }
            var citationReceipt = new CitationReceiptModel()
            {
                CitationNumber      = citation.CitationNumber,
                AccountNumber       = cachedAccount.Number,
                AccountName         = cachedAccount.Name,
                AccountCity         = commonAccount.City.Name,
                AccountState        = commonAccount.City.StateCode,
                ViolationCode       = citation.Violation != null ? citation.Violation.Code : "",
                ViolationTitle      = citation.Violation != null ? citation.Violation.Name : "",
                ViolationState      = citation.State,
                ViolationCity       = citation.City,
                LicensePlate        = citation.LicensePlate,
                LicenseState        = citation.LicenseState,
                ViolationLatitude   = citation.Latitude,
                ViolationLongitude  = citation.Longitude,
                ViolationCreatedUTC = citation.Violation != null ? citation.Violation.CreateUtc : DateTime.UtcNow,
            };

            var data = JsonConvert.SerializeObject(citationReceipt);

            TextWriter tw = File.CreateText(FileLocation);

            tw.WriteLine(data);
            tw.Close();


            return(true);
        }