add better log messages for multi url checks

This commit is contained in:
Pierce 2023-08-25 15:13:22 -04:00
parent 609f7ea083
commit f4345c19c0
No known key found for this signature in database
GPG Key ID: EC79465B0E865E47
9 changed files with 158 additions and 60 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.luarc.json
lua/.luarc.json

View File

@ -15,6 +15,7 @@ local function includeShared( f )
include( f )
end
includeShared( "cfc_http_restrictions/shared/logging.lua" )
includeShared( "cfc_http_restrictions/shared/config_loader.lua" )
includeShared( "cfc_http_restrictions/shared/filetypes.lua" )
includeShared( "cfc_http_restrictions/shared/list_manager.lua" )

View File

@ -1,3 +1,5 @@
---@param listView DListView
---@param value string
local function removeByValue( listView, value )
for i, line in pairs( listView:GetLines() ) do
if line:GetValue( 1 ) == value then
@ -48,7 +50,7 @@ local function populatePanel( form )
list:AddLine( v, "yes" )
end
local block = form:Button( "Block" )
local block = form:Button( "Block", "" )
block.DoClick = function()
local v = textEntry:GetValue()
if not CFCHTTP.blockAddress( v ) then return end

View File

@ -1,44 +1,3 @@
local shouldLogAllows = CreateConVar( "cfc_http_restrictions_log_allows", 1, FCVAR_ARCHIVE, "Should the HTTP restrictions log allowed HTTP requests?", 0, 1 )
local shouldLogBlocks = CreateConVar( "cfc_http_restrictions_log_blocks", 1, FCVAR_ARCHIVE, "Should the HTTP restrictions log blocked HTTP requests?", 0, 1 )
local verboseLogging = CreateConVar( "cfc_http_restrictions_log_verbose", 0, FCVAR_ARCHIVE, "Should the HTTP restrictions log include verbose messages?", 0, 1 )
local COLORS = {
RED = Color( 255, 0, 0 ),
GREEN = Color( 0, 255, 0 ),
GREY = Color( 136, 151, 158 ),
YELLOW = Color( 235, 226, 52 )
}
local function logRequest( method, url, fileLocation, allowed, noisy )
if allowed and not shouldLogAllows:GetBool() then return end
if not shouldLogBlocks:GetBool() then return end
local isVerbose = verboseLogging:GetBool()
local requestStatus = allowed and "ALLOWED" or "BLOCKED"
local requestColor = allowed and COLORS.GREEN or COLORS.RED
if not url then
url = "unknown"
elseif isVerbose == false then
local address = CFCHTTP.GetAddress( url )
if noisy then return end
url = address
end
MsgC(
requestColor, requestStatus,
COLORS.GREY, ": ",
COLORS.YELLOW, method,
COLORS.GREY, " - ",
COLORS.YELLOW, url, "\n"
)
if isVerbose then
MsgC( COLORS.YELLOW, " ", fileLocation, "\n" )
end
end
local function wrapHTTP()
_HTTP = _HTTP or HTTP
print( "HTTP wrapped, original function at '_G._HTTP'" )
@ -49,7 +8,13 @@ local function wrapHTTP()
local noisy = options and options.noisy
local stack = string.Split( debug.traceback(), "\n" )
logRequest( req.method, req.url, stack[3], isAllowed, noisy )
CFCHTTP.LogRequest( {
noisy = noisy,
method = req.method,
fileLocation = stack[3],
urls = { { url = req.url, status = isAllowed and "allowed" or "blocked" } },
} )
local onFailure = req.failed
if not isAllowed then
if onFailure then onFailure( "URL is not whitelisted" ) end
@ -63,13 +28,20 @@ local function wrapFetch()
_http_Fetch = _http_Fetch or http.Fetch
print( "http.Fetch wrapped, original function at '_http_Fetch'" )
---@diagnostic disable-next-line: duplicate-set-field
http.Fetch = function( url, onSuccess, onFailure, headers )
local options = CFCHTTP.GetOptionsForURL( url )
local isAllowed = options and options.allowed
local noisy = options and options.noisy
local stack = string.Split( debug.traceback(), "\n" )
logRequest( "GET", url, stack[3], isAllowed, noisy )
CFCHTTP.LogRequest( {
noisy = noisy,
method = "GET",
fileLocation = stack[3],
urls = { { url = url, status = isAllowed and "allowed" or "blocked" } },
} )
if not isAllowed then
if onFailure then onFailure( "URL is not whitelisted" ) end
return
@ -83,13 +55,20 @@ local function wrapPost()
_http_Post = _http_Post or http.Post
print( "http.Post wrapped, original function at '_http_Post'" )
---@diagnostic disable-next-line: duplicate-set-field
http.Post = function( url, params, onSuccess, onFailure, headers )
local options = CFCHTTP.GetOptionsForURL( url )
local isAllowed = options and options.allowed
local noisy = options and options.noisy
local stack = string.Split( debug.traceback(), "\n" )
logRequest( "POST", url, stack[3], isAllowed, noisy )
CFCHTTP.LogRequest( {
noisy = noisy,
method = "POST",
fileLocation = stack[3],
urls = { { url = url, status = isAllowed and "allowed" or "blocked" } },
} )
if not isAllowed then
if onFailure then onFailure( "URL is not whitelisted" ) end
return
@ -117,8 +96,15 @@ local function wrapPlayURL()
local isAllowed = options and options.allowed
local noisy = options and options.noisy
local logData = {
noisy = noisy,
method = "GET",
fileLocation = stack[3],
urls = { { url = url, status = isAllowed and "allowed" or "blocked" } },
}
if not isAllowed then
logRequest( "GET", url, stack[3], isAllowed, noisy )
CFCHTTP.LogRequest( logData )
if callback then callback( nil, CFCHTTP.BASS_ERROR_BLOCKED_URI, "BASS_ERROR_BLOCKED_URI" ) end
return
end
@ -131,15 +117,15 @@ local function wrapPlayURL()
end
if #uris == 0 then
logRequest( "GET", url, stack[3], isAllowed, noisy )
CFCHTTP.LogRequest( logData )
_sound_PlayURL( url, flags, callback )
return
end
options = CFCHTTP.GetOptionsForURLs( uris )
isAllowed = options.combined.allowed
local multiOptions = CFCHTTP.GetOptionsForURLs( uris )
isAllowed = multiOptions.combined.allowed
logRequest( "GET", url, stack[3], isAllowed, noisy )
CFCHTTP.LogRequest( logData )
if not isAllowed then
if callback then callback( nil, CFCHTTP.BASS_ERROR_BLOCKED_CONTENT, "BASS_ERROR_BLOCKED_CONTENT" ) end
return
@ -170,12 +156,13 @@ local function wrapHTMLPanel( panelName )
controlTable.SetHTML = function( self, html, ... )
local stack = string.Split( debug.traceback(), "\n" )
local logUrls = {}
html = CFCHTTP.ReplaceURLs( html, function( url )
local options = CFCHTTP.GetOptionsForURL( url )
local isAllowed = options and options.allowed
local noisy = true -- this will be really spammy so set it to noisy by default
logRequest( "GET", url, stack[3], isAllowed, noisy )
local logUrl = { url = url, status = isAllowed and "allowed" or "replaced" }
table.insert( logUrls, logUrl )
if not isAllowed then
return CFCHTTP.GetRedirectURL( url )
@ -183,25 +170,39 @@ local function wrapHTMLPanel( panelName )
return url
end )
CFCHTTP.LogRequest( {
noisy = true,
method = "GET",
fileLocation = stack[3],
urls = logUrls,
} )
return _G[setHTML]( self, html, ... )
end
controlTable.RunJavascript = function( self, js )
local stack = string.Split( debug.traceback(), "\n" )
local logUrls = {}
js = CFCHTTP.ReplaceURLs( js, function( url )
local options = CFCHTTP.GetOptionsForURL( url )
local isAllowed = options and options.allowed
local noisy = true -- this will be really spammy so set it to noisy by default
logRequest( "GET", url, stack[3], isAllowed, noisy )
local logUrl = { url = url, status = isAllowed and "allowed" or "replaced" }
table.insert( logUrls, logUrl )
if not isAllowed then
return CFCHTTP.GetRedirectURL( url )
end
return url
end )
CFCHTTP.LogRequest( {
noisy = true,
method = "GET",
fileLocation = stack[3],
urls = logUrls,
} )
return _G[runJavascript]( self, js )
end
@ -211,7 +212,12 @@ local function wrapHTMLPanel( panelName )
local noisy = options and options.noisy
local stack = string.Split( debug.traceback(), "\n" )
logRequest( "GET", url, stack[3], isAllowed, noisy )
CFCHTTP.LogRequest( {
noisy = noisy,
method = "GET",
fileLocation = stack[3],
urls = { { url = url, status = isAllowed and "allowed" or "blocked" } },
} )
if not isAllowed then
url = CFCHTTP.GetRedirectURL( url )

View File

@ -1,6 +1,6 @@
AddCSLuaFile()
---@alias WhitelistAddressOption { allowed: boolean|nil, noisy: boolean|nil, permanent: boolean|nil }
---@alias WhitelistAddressOption { allowed: boolean|nil, noisy: boolean|nil, permanent: boolean|nil, pattern: boolean|nil }
---@class WhitelistConfig
---@field version string

View File

@ -47,11 +47,14 @@ function CFCHTTP.LoadConfigsServer()
CFCHTTP.loadLuaConfigs( "cfc_http_restrictions/configs/server/" )
end
---@param old any
---@param new WhitelistConfig
---@return WhitelistConfig
function CFCHTTP.mergeConfigs( old, new )
if new.version == "1" then
if new.wrapHTMLPanels ~= nil then old.wrapHTMLPanels = new.wrapHTMLPanels end
if new.defaultOptions ~= nil then old.defaultOptions = new.defaultOptions end
if new.defaultAssetURIOption ~= nil then old.defaultAssetURIOption = new.defaultAssetURIOption end
if new.defaultAssetURIOptions ~= nil then old.defaultAssetURIOptions = new.defaultAssetURIOptions end
for domain, options in pairs( new.addresses ) do
local currentOptions = old.addresses[domain]
@ -68,19 +71,23 @@ function CFCHTTP.mergeConfigs( old, new )
return old
end
---@param cfg WhitelistConfig
---@return WhitelistConfig
function CFCHTTP.CopyConfig( cfg )
return util.JSONToTable( util.TableToJSON( cfg ) )
end
---@param config WhitelistConfig
function CFCHTTP.SaveFileConfig( config )
file.Write( "cfc_cl_http_whitelist_config.json", util.TableToJSON( config, true ) )
notification.AddLegacy( "Saved http whitelist", NOTIFY_GENERIC, 5 )
end
---@return WhitelistConfig|nil
function CFCHTTP.ReadFileConfig()
local fileData = file.Read( "cfc_cl_http_whitelist_config.json" )
if not fileData then return end
if not fileData then return nil end
return util.JSONToTable( fileData )
end

View File

@ -14,7 +14,8 @@ local function escapeAddr( addr )
return escapedCache[addr]
end
-- TODO reimmplement caching
---@param url string
---@return WhitelistAddressOption
function CFCHTTP.GetOptionsForURL( url )
if not url then return CFCHTTP.config.defaultOptions end

View File

@ -0,0 +1,77 @@
local COLORS = {
RED = Color( 255, 0, 0 ),
GREEN = Color( 0, 255, 0 ),
GREY = Color( 136, 151, 158 ),
ORANGE = Color( 255, 165, 0 ),
YELLOW = Color( 235, 226, 52 )
}
local shouldLogAllows = CreateConVar( "cfc_http_restrictions_log_allows", 1, FCVAR_ARCHIVE, "Should the HTTP restrictions log allowed HTTP requests?", 0, 1 )
local shouldLogBlocks = CreateConVar( "cfc_http_restrictions_log_blocks", 1, FCVAR_ARCHIVE, "Should the HTTP restrictions log blocked HTTP requests?", 0, 1 )
local verboseLogging = CreateConVar( "cfc_http_restrictions_log_verbose", 0, FCVAR_ARCHIVE, "Should the HTTP restrictions log include verbose messages?", 0, 1 )
local statusColors = {
ALLOWED = COLORS.GREEN,
BLOCKED = COLORS.RED,
REPLACED = COLORS.ORANGE,
UNKNOWN = COLORS.GREY
}
---@class CFCHTTPLogRequestInput
---@field method string
---@field urls { url: string, status: string }[]
---@field fileLocation string
---@field noisy boolean|nil
---@param input CFCHTTPLogRequestInput
function CFCHTTP.LogRequest( input )
if input.noisy and not verboseLogging:GetBool() then return end
for _, v in ipairs( input.urls ) do
if not verboseLogging:GetBool() then
local url = CFCHTTP.GetAddress( v.url ) or v.url
v.url = url
end
end
if #input.urls == 1 then
local url = input.urls[1].url
local requestStatus = string.upper( input.urls[1].status ) or "UNKNOWN"
local requestColor = statusColors[requestStatus] or COLORS.GREY
if not shouldLogAllows:GetBool() and requestStatus == "ALLOWED" then return end
if not shouldLogBlocks:GetBool() and requestStatus == "BLOCKED" then return end
MsgC(
requestColor, requestStatus,
COLORS.GREY, ": ",
COLORS.YELLOW, input.method,
COLORS.GREY, " - ",
COLORS.YELLOW, url, "\n"
)
if verboseLogging:GetBool() then
MsgC( COLORS.YELLOW, " ", input.fileLocation, "\n" )
end
return
end
local msg = { COLORS.YELLOW, tostring( #input.urls ), " urs filtered:\n", COLORS.YELLOW, " ", input.fileLocation, "\n" }
for _, v in pairs( input.urls or {} ) do
local url = v.url
local requestStatus = string.upper( v.status ) or "UNKNOWN"
local requestColor = statusColors[requestStatus] or COLORS.GREY
table.insert( msg, requestColor )
table.insert( msg, "\t" .. requestStatus )
table.insert( msg, COLORS.GREY )
table.insert( msg, ": " )
table.insert( msg, COLORS.YELLOW )
table.insert( msg, input.method )
table.insert( msg, COLORS.GREY )
table.insert( msg, " - " )
table.insert( msg, COLORS.YELLOW )
table.insert( msg, url )
table.insert( msg, "\n" )
end
MsgC( unpack( msg ) )
end

View File

@ -49,7 +49,9 @@ function CFCHTTP.ReplaceURLs( text, f )
return html
end
---@type table<string, string>
local parsedAddressCache = {}
---@param url string
---@return string|nil
function CFCHTTP.GetAddress( url )