Module:Sensitive IP addresses/API: Difference between revisions

Content deleted Content added
first go at defining the API
dump a bunch of code to test this and Module:IP: some of the code, after refactoring, would be useful for this module; see talk page for test results
Line 103:
-- }
--------------------------------------------------------------------------------
-- Q&D demo of loading data from [[Module:Sensitive IP addresses/list]]
-- into a structure that could be used to determine whether a particular
-- IP or subnet overlaps a sensitive range.
-- If used, this would be greatly refactored and possibly split to
-- [[Module:Sensitive IP addresses/data]].
--
-- Usage in a sandbox:
-- {{#invoke:Sensitive IP addresses|main}}
 
local function main()
-- Test Module:IP.
----------------------------------------------------------------------------
-- An IP collection in Module:IP should hold both IPv4 and IPv6 lists and
-- it would use the appropriate list depending on the object queried?
-- That would make this code more straight forward.
----------------------------------------------------------------------------
-- Support stuff
----------------------------------------------------------------------------
local modcode = require('Module:IP')
local IPAddress = modcode.IPAddress
local Subnet = modcode.Subnet
local IPv4Collection = modcode.IPv4Collection
local IPv6Collection = modcode.IPv6Collection
local Collection = {}
Collection.__index = Collection
do
function Collection:add(item)
if item ~= nil then
self.n = self.n + 1
self[self.n] = item
end
end
function Collection:join(sep)
return table.concat(self, sep)
end
function Collection:sort(comp)
table.sort(self, comp)
end
function Collection.new()
return setmetatable({n = 0}, Collection)
end
end
local function getObject(ipStr)
-- Parse a string and return an appropriate object:
-- IPv4 or IPv6 IP or subnet, or nil.
-- TODO This should be in Module:IP (see IPCollection:_store).
local maker
if ipStr:find('/', 1, true) then
maker = Subnet.new
else
maker = IPAddress.new
end
local success, obj = pcall(maker, ipStr)
if success then
return obj
end
return nil
end
local function preBlock(text)
-- Pre tags returned by a module do not act like wikitext <pre>...</pre>.
return '<pre>\n' ..
mw.text.nowiki(text) ..
(text:sub(-1) == '\n' and '' or '\n') ..
'</pre>\n'
end
----------------------------------------------------------------------------
-- Load sensitive IP information
----------------------------------------------------------------------------
local function loadList(modname)
-- Return a table to query an IP/subnet wrt sensitive ranges.
local data = {
subnetToInfo = {},
v4Collection = IPv4Collection.new(),
v6Collection = IPv6Collection.new(),
}
local sensitiveList = mw.loadData(modname)
for i, info in ipairs(sensitiveList) do
for _, r in ipairs({
{key = 'ipv4Ranges', list = data.v4Collection},
{key = 'ipv6Ranges', list = data.v6Collection},
}) do
local rangeStrings = info[r.key]
if rangeStrings then
for _, str in ipairs(rangeStrings) do
local subnet = Subnet.new(str)
r.list:addSubnet(subnet)
data.subnetToInfo[subnet] = info
end
end
end
end
return data
end
----------------------------------------------------------------------------
-- Run test using Module:IP
----------------------------------------------------------------------------
local results = Collection.new()
local data = loadList('Module:Sensitive IP addresses/list')
for _, ipStr in ipairs({
-- Each of the following is tested against the sensitive list.
'143.228.19.123',
'2620:0:E21:9F2::',
'131.132.224.0/19',
'198.35.27.255',
'2620:0:860::1',
'1.2.3.4',
'11.12.13.192/26',
'2001:db8::abcd',
'2001:db8::/72',
}) do
local obj = getObject(ipStr)
if obj then
local isPresent, clashObj
local col = obj:getVersion() == 'IPv4' and
data.v4Collection or data.v6Collection
if obj.getNextIP then -- dirty trick to check if obj is an IP
isPresent, clashObj = col:containsIP(obj)
else
isPresent, clashObj = col:overlapsSubnet(obj)
end
results:add('')
results:add('IP or range under test: ' .. ipStr)
if isPresent then
local info = data.subnetToInfo[clashObj]
if info then
results:add(' sensitive: ' .. clashObj)
results:add(' name: ' .. (info.name or '?'))
results:add(' id: ' .. (info.id or '?'))
results:add(' description: ' .. (info.description or '?'))
results:add(' reason: ' .. (info.reason or '?'))
else
-- Should not occur!
results:add(' info not found!')
end
else
results:add(' not sensitive')
end
else
-- Report problem?
end
end
return preBlock(results:join('\n'))
end
 
--------------------------------------------------------------------------------
Line 109 ⟶ 253:
 
local p = {}
p.main = main
 
function p.isValidSensitivityReason(s)