Naar inhoud springen

Module:Layout/Production/Interface/Security

Uit Wikibooks
 Deze module is nog in ontwikkeling (versie 0.0) en wordt getest.

De Module:Layout is bedoeld om snel, consistent en uitgebreid een pagina op te maken.
Er is een op de module afgestemde handleiding over deze onderwijswiki beschikbaar.

De module wordt geïnitialiseerd met de configuratie in Module:Layout/Production/Configuration.

Controleer op scriptfouten, lintfouten of opmaak notificaties.

Test

[bewerken]

Deze module wordt getest door Module:Layout/Production/Test/Security.

Yes All 5 tests are ok.

NameExpectedActual
Yestest_security_authentication
Yestest_security_declaration
Yestest_security_frisk
Yestest_security_invalid_call
Yestest_security_scan

Code

[bewerken]
-- Security validates the input passed to Module:Layout before rendering starts.
-- It records user-facing mistakes and sets call.pass to false when rendering
-- should be blocked.
local security = {};
local frisk = {};
local report = {};

-- Check whether this environment was invoked through its configured template.
function security.authentication( call )
    if not call or type(call) ~= "table" or not call.include then return call; end
	call.add_new_debug( call.message.DEBUG.INVOKER, tostring( call.invoker ), report.debugging( call ) );
	if ( call.invoker ~= call.template ) then
        call.add_new_mistake ( call.message.MISTAKE.NO_INTERFACE_TEMPLATE );
        call.add_debug( call.message.DEBUG.NO_INTERFACE_TEMPLATE );
	end
    return call;
end

-- Check internal #invoke parameter names before translated template names are handled.
function security.declaration( call )
    if not call or type(call) ~= "table" or not call.include then return call; end
	-- Array search is used to compare against the configured parameter whitelist.
	local array  = call.include( "array" );

    -- Named #invoke parameters must be listed in hook.PARAMETER.
    for key, value in pairs( call.named ) do
        if not array.search( call.hook.PARAMETER, key, true ) then 
        	call.add_new_mistake ( call.message.MISTAKE.WRONG.INVOKE_PARAMETER, key, key, value );
        end
    end
	return call;
end

-- Validate all configured parameter values after names have been accepted.
function security.frisk( call )
    if not call or type(call) ~= "table" or not call.include then return call; end
	-- Each parameter has an optional frisk function with its own value rules.
	local array, frisk  = call.include( "array", "frisk" );

    local mistakes_before_value_check = #call.mistake;
	for _, parameter in ipairs( call.hook.PARAMETER ) do
		-- Optimized: Pass the call object directly instead of deep-copying it 15+ times.
		local mistake, m1, m2, m3, m4, m5, m6 = frisk[ parameter ]( call );
        if mistake then
        	call.add_new_mistake( mistake, m1, m2, m3, m4, m5, m6 );
        end
	end
	local value_mistake = #call.mistake - mistakes_before_value_check;

    if value_mistake == 0 then call.add_debug( call.message.DEBUG.VALUES_OK ); end
	if value_mistake == 1 then call.add_mistake( call.message.DEBUG.VALUE_MISTAKE ); end
    if value_mistake > 1  then call.add_mistake( call.message.DEBUG.VALUE_MISTAKES, value_mistake ); end
    return call;
end

-- Scan the original page wikitext for translated template parameter names.
-- A page may contain multiple template calls, so every matching call is checked.
function security.scan( call ) -- returns call object with security information
    if not call or type(call) ~= "table" or not call.include then return call; end
    -- Memory optimization: Skip expensive wikitext scanning in production.
    if call.environment == "production" then return call; end
	local extract, array  = call.include( "extract", "array" );

 	-- Module documentation can expose source text containing template definitions,
 	-- which would produce false positives if scanned as normal page content.
-- 	if call.caller:inNamespace( "Module" ) and call.caller.subpageText ~= "doc" then return call; end
 	
    call.add_new_debug( call.message.DEBUG.CALLER,  tostring( call.invoker), tostring( call.caller ) );

    local caller_content =  call.caller:getContent();
    local calling_templates = extract.template( caller_content, call.message.TEMPLATENAME, call );
    local parameter_mistake = {};
    for index, value in ipairs( calling_templates ) do
     	for key, v in pairs( value ) do
     		-- Unnamed parameters remain free-form; named parameters must be localized hooks.
            if not tonumber( key ) and not array.search( call.message.HOOK.PARAMETER, key, true ) then
            	parameter_mistake[ #parameter_mistake + 1 ] = key;
		    	call.add_new_mistake( call.message.MISTAKE.WRONG.TEMPLATE_PARAMETER, key, key, v, table.concat( call.message.HOOK.PARAMETER, ", ") );
            end
        end
    end
    -- The mistakes are already stored. The debug reports only the number of mistakes found.
    if #parameter_mistake == 0 then call.add_debug( call.message.DEBUG.PARAMETERS_OK ); end
    if #parameter_mistake == 1 then call.add_debug( call.message.DEBUG.PARAMETER_MISTAKE, parameter_mistake[1] ); end
    if #parameter_mistake > 1  then call.add_debug( call.message.DEBUG.PARAMETER_MISTAKES, #parameter_mistake, table.concat( parameter_mistake, ", ") ); end
    return call;
end

-- Reconstruct the #invoke call for debug feedback.
function report.debugging( call )
    if not call or type(call) ~= "table" then return ""; end
	local call_string = "{{#invoke:Layout|main";
    -- Add named parameters.
    if type(call.named) == "table" then
        for key, value in pairs( call.named ) do
            call_string = call_string .. "|" .. key .. "=" .. value;
        end
    end

    -- Add unnamed parameters.
    if type(call.unnamed) == "table" then
        for _, value in ipairs( call.unnamed ) do
            call_string = call_string .. "|" .. value;
        end
    end
    return call_string .. "}}";
end

return security;
Informatie afkomstig van Wikibooks NL, een onderdeel van de Wikimedia Foundation.