Jump to content

ICT:FinalConfig-Clutter and protection: Difference between revisions

From Costa Sano MediaWiki
No edit summary
No edit summary
Line 1: Line 1:
= Final Configuration: general clutter reduction and page protection =
= Final Configuration: Clutter Reduction and Protection =
Document revison: {{#time:Y-m-d|{{REVISIONTIMESTAMP}}}} by {{REVISIONUSER}}
Document revision: {{#time:Y-m-d|{{REVISIONTIMESTAMP}}}} by {{REVISIONUSER}}


The project is using a lot of namespaces, both system default ones and proprietary ones. Although the general default philosophy of MediaWiki is to be as open as possible, we go for a as closed as possible scenario.
== Purpose and Philosophy ==
This needs a lot a configuration and during 3 days of struggling with this configuration it was observed that it is not fully possible with too much extra lines of code to deal with this ending up in a stable and predictable system.
The historical heritage project as intended to be used by senior people mostly older than 70 and have historical reflexes more than IT reflexes.
A very first requirement is the use of DARK MODE and for now this is only present in an easy way in the vector-2022 skin. However this skin is rather complex so we learned the lesson the hard way not to use too much private css. An experiment to use the more simpler Minerva skin for all or a number of namespaces was not successfull due to the lack of Dark mode.
This finally means that we ended up in extra configuration for vector-2022 in constant dark mode with clutter reduction and protection realized in LocalSystems.php and some elementary css files.


The idea is the following:
This MediaWiki installation supports a historical heritage project used primarily by senior researchers (mostly 70+). Their workflow is simple, and their expectations are shaped by historical research habits rather than IT experience. The system must therefore be:


# Anonymous users should see the final public documents from the reserach effort, without any MediaWiki clutter.
* As closed as reasonably possible 
# Sysop of course should be capable of dealing with the system as a normal sysop
* Predictable and stable 
# The (only) users = senior historians, should only have access to
* Minimal in clutter 
## Dashboard: namespace for introducing data - workflow and help subpages are also foreseen here.
* Dark‑mode by default 
## Research: namespace for creating, editing and reviewing publication pages coming out of the research These, once validated and accepted by the users (Costa Sano club members), should then be copied to the (Main) namespace for public access.
* Safe against accidental clicks  
## Each data entity has its own namespace with the pages concerning the data of that entity NOT accessible by users. Data input and editing is only accessible via the Dashboard.
## Remark: all access to the data goes through the PageForms extension. Forbidding direct access to data has no influence on the PageForms access.


This ens up in a user workflow:
MediaWiki’s default philosophy is openness. After three days of experimentation, it became clear that a fully closed system is not feasible without brittle hacks. Instead, this configuration aims for a stable, predictable, minimally exposed environment that still respects MediaWiki’s architecture.


# Introducing and documenting media data via the Dashboard namespace
Dark mode is essential. Only Vector‑2022 provides a reliable dark mode, so the system standardizes on this skin. Attempts to use Minerva failed due to lack of dark mode support.
# Followed by the creating of pages to be made available to the general public in our environment, and optionally moved to Wikipedia.


There are no other users in the system than the onces described above.
All data entry is performed through PageForms, and direct access to data namespaces is intentionally blocked. This ensures that users interact only with structured forms, not raw pages.


== Configuring the correct skin ==
== User Roles and Workflow ==
 
=== User Types ===
* '''Anonymous visitors''' 
: Can read only the final public documents in the Main namespace 
: Should see no MediaWiki clutter 
 
* '''Club Members (users)''' 
: Can create and edit research drafts 
: Can enter data only through the Dashboard (PageForms) 
: Cannot access system areas or data namespaces directly 
 
* '''Sysop''' 
: Full administrative and interface control 
: Sees the full MediaWiki interface 
 
=== Workflow Overview ===
 
<pre>
Anonymous → Main (read-only)
 
Users → Dashboard (data entry via PageForms)
      → Research (drafting and reviewing)
      → No direct access to data namespaces
 
Sysop → All namespaces + interface
</pre>
 
=== Publishing Flow ===
# Users introduce and document data via Dashboard forms. 
# Users create and refine publication pages in Research. 
# Once validated, pages are copied to Main for public access. 
# Optionally, content may be exported to Wikipedia.
 
== Configuring the Skin ==


LocalSystems.php snippet
<pre>
<pre>
# =================================================
# =================================================
# SKIN & INTERFACE
# SKIN & INTERFACE
# =================================================
# =================================================
# --- RESTORE VECTOR 2022 ---
wfLoadSkin( 'Vector' );
wfLoadSkin( 'Vector' );
$wgDefaultSkin = "vector-2022";
$wgDefaultSkin = "vector-2022";


# --- ENABLE NATIVE DARK MODE (For Vector 2022) ---
# Enable native dark mode
# This unlocks the "Appearance" menu for users without manual CSS hacks.
$wgVectorNightMode = [
$wgVectorNightMode = [
     'beta' => true,
     'beta' => true,
Line 44: Line 68:
];
];


# --- OPTIONAL: Force 'Dark' as the default for all users ---
# Force dark mode for all users
$wgDefaultUserOptions['vector-theme'] = 'night';
$wgDefaultUserOptions['vector-theme'] = 'night';
</pre>
</pre>


= Protection =
== Protection Model ==
What is documented by MediaWiki as of using the following approach:  
 
MediaWiki cannot be inverted into a “deny everything, allow selectively” model. 
Lockdown adds restrictions, but it cannot:


# forbid everything
* override global permissions 
# and then allow specific function and actions (with Lockdown)
* grant permissions 
* create a deny‑by‑default environment 


gives no result at all, because this is against the spirit of what Lockdown is supposed to do.
Therefore, the configuration below uses global permissions, namespace protection, and CSS‑based interface reduction.


The adopted solution is as follows:
=== Global Permissions ===


LocalSystems.php snippet
<pre>
<pre>
 
# Anonymous
###########################################################################
# STABLE INTERFACE MODEL - MW 1.43 / PHP 8.2 COMPATIBLE
###########################################################################
 
# 1. GLOBAL PERMISSIONS
$wgGroupPermissions['*']['read']          = true;
$wgGroupPermissions['*']['read']          = true;
$wgGroupPermissions['*']['edit']          = false;
$wgGroupPermissions['*']['edit']          = false;
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['createaccount'] = false;


# Clubmembers: Full drafting in Research, but locked system areas
# Users
$wgGroupPermissions['user']['read']      = true;
$wgGroupPermissions['user']['read']      = true;
$wgGroupPermissions['user']['edit']      = true;
$wgGroupPermissions['user']['edit']      = true;
$wgGroupPermissions['user']['upload']    = false;
$wgGroupPermissions['user']['upload']    = false;


# Sysop: Absolute interface control
# Sysop
$wgGroupPermissions['sysop']['editinterface'] = true;
$wgGroupPermissions['sysop']['editinterface'] = true;
$wgGroupPermissions['sysop']['upload']        = true;
$wgGroupPermissions['sysop']['upload']        = true;
</pre>


# 2. NAMESPACE PROTECTION
=== Namespace Protection (Consolidated) ===
$wgNamespaceProtection[NS_MAIN]      = [ 'protect' ];
$wgNamespaceProtection[NS_ICT]      = [ 'editinterface' ];
$wgNamespaceProtection[NS_DASHBOARD] = [ 'editinterface' ];


# 3. CONTENT DEFINITION
<pre>
$wgNamespaceProtection[NS_MAIN]      = [ 'protect' ];        # Public library
$wgNamespaceProtection[NS_ICT]      = [ 'editinterface' ];  # Technical docs
$wgNamespaceProtection[NS_DASHBOARD] = [ 'editinterface' ];  # App layout
</pre>
 
=== Content Namespaces ===
 
<pre>
$wgContentNamespaces = [
$wgContentNamespaces = [
     NS_MAIN, NS_RESEARCH, NS_ICT, NS_DASHBOARD,
     NS_MAIN, NS_RESEARCH, NS_ICT, NS_DASHBOARD,
     NS_CHAPTER, NS_PLACE, NS_ORGANISATION, NS_PERSON, NS_HERITAGE, NS_ASSET
     NS_CHAPTER, NS_PLACE, NS_ORGANISATION,
    NS_PERSON, NS_HERITAGE, NS_ASSET
];
];
$wgNamespacesWithSubpages[NS_DASHBOARD] = true;
$wgNamespacesWithSubpages[NS_DASHBOARD] = true;
</pre>


# 4. SAFE SIDEBAR HOOK (MW 1.43 Signature)
=== Sidebar Simplification ===
# This hook modifies the sidebar content only for non-admins.
 
# Uses static relative paths to prevent 'Title' object initialization crashes.
A custom sidebar is injected for all non‑sysop users.
This avoids exposing MediaWiki’s default navigation.
 
'''Important note for successors:''' 
This uses hardcoded paths. If <code>$wgArticlePath</code> or namespace names change, the sidebar must be updated.
 
<pre>
$wgHooks['SidebarBeforeOutput'][] = function ( $skin, &$sidebar ) {
$wgHooks['SidebarBeforeOutput'][] = function ( $skin, &$sidebar ) {
     $user = $skin->getUser();
     $user = $skin->getUser();
   
 
    # Only simplify for non-admins (Club Members)
     if ( !$user->isAllowed( 'editinterface' ) ) {
     if ( !$user->isAllowed( 'editinterface' ) ) {
        # We use the $wgArticlePath format (usually /Dashboard:Main)
         $sidebar = [
         $sidebar = [
             'Project Navigation' => [
             'Project Navigation' => [
                 [ 'text' => 'Dashboard', 'href' => '/Dashboard:Main' ],
                 [ 'text' => 'Dashboard',     'href' => '/Dashboard:Main' ],
                 [ 'text' => 'Research Area', 'href' => '/Research:Main' ],
                 [ 'text' => 'Research Area', 'href' => '/Research:Main' ],
             ],
             ],
             'Account' => [
             'Account' => [
Line 112: Line 146:
     return true;
     return true;
};
};
</pre>


# 5. NAMESPACE PROTECTION (Keep the seniors safe)
=== Cargo Hardening ===
$wgNamespaceProtection[NS_MAIN]      = [ 'protect' ];      // Locked Library
$wgNamespaceProtection[NS_ICT]      = [ 'editinterface' ]; // Locked Technical Docs
$wgNamespaceProtection[NS_DASHBOARD] = [ 'editinterface' ]; // Locked App Layout


# 6. CARGO SECURITY (The "Simple" Block)
<pre>
# This stops the 'Cargo data' link from actually working for users
$wgGroupPermissions['user']['runcargoqueries'] = false;
$wgGroupPermissions['user']['runcargoqueries'] = false;
$wgGroupPermissions['user']['recreatecargodata'] = false;
$wgGroupPermissions['user']['recreatecargodata'] = false;
</pre>


# 7. This hides the 'Edit' button and replaces it with 'View Source' for non-admins
=== Upload Restrictions ===
$wgNamespaceProtection[NS_DASHBOARD] = ['editinterface'];
$wgNamespaceProtection[NS_MAIN]      = ['protect'];
$wgNamespaceProtection[NS_ICT]      = ['editinterface'];


# 8. Disable direct uploads for users
<pre>
$wgGroupPermissions['user']['upload'] = false;
$wgGroupPermissions['user']['upload']       = false;
$wgGroupPermissions['user']['reupload'] = false;
$wgGroupPermissions['user']['reupload']     = false;
$wgGroupPermissions['user']['reupload-own'] = false;
$wgGroupPermissions['user']['reupload-own'] = false;


# 9. Sysop keeps upload rights
$wgGroupPermissions['sysop']['upload']       = true;
$wgGroupPermissions['sysop']['upload'] = true;
$wgGroupPermissions['sysop']['reupload']     = true;
$wgGroupPermissions['sysop']['reupload'] = true;
$wgGroupPermissions['sysop']['reupload-own'] = true;
$wgGroupPermissions['sysop']['reupload-own'] = true;
</pre>


# -------------------------------------------------
=== Optional Hardening ===
# OPTIONAL HARDENING
# -------------------------------------------------


<pre>
$wgNonincludableNamespaces[] = NS_ICT;
$wgNonincludableNamespaces[] = NS_ICT;


#Never redirect a page - bypass login redirect problem/bug
# Avoid login redirect bug
$wgRedirectOnLogin = "Hoofdpagina";
$wgRedirectOnLogin = "Hoofdpagina";
############################################################
# END OF SIMPLE ANTI CLUTTER AND PROTECTION  MODEL
############################################################
</pre>
</pre>
As one may observe it is not a simple taks to reduce the clutter and protect the environment against accidentel and curiously clicking links that could lead to corruption of the system.
Point 4 introduces a special sidebar for replacing the classical MediaWiki left sidebar. Only permitted pages are listed in the sidebar.


It has been decided to make disappear, except for the sysop of the classical bar on top of a text.
== Interface Clutter Reduction (CSS) ==
<pre>
Namespace Discussion Read Edit Edit source View history
</pre>
This avoids a lot of possible problems with the users.


This is realised by 2 css group files:
=== User View (MediaWiki:Group-user.css) ===


MediaWiki:Group-user.css
<pre>
<pre>
/* CSS placed here will affect registered users only */
/* Hide Top Bar & Right Column for Users in Dashboard & Main */
/* Hide Top Bar & Right Column for Users in Dashboard & Main */
.ns-3020 .vector-page-toolbar,  
.ns-3020 .vector-page-toolbar,  
Line 189: Line 203:
</pre>
</pre>


and a second one restoring the bar for the sysop (as sysop is also considered a user)
=== Sysop View (MediaWiki:Group-sysop.css) ===


MediaWIki:Group-sysop.css
<pre>
<pre>
/* MediaWiki:Group-sysop.css - Fluid Admin View */
/* Restore the Top Toolbar */
 
/* 1. Restore the Top Toolbar (Read, Edit, History) */
html body.skin-vector-2022 .vector-page-toolbar {
html body.skin-vector-2022 .vector-page-toolbar {
     display: flex !important;
     display: flex !important;
    visibility: visible !important;
}
}


/* 2. Restore the Right Column Tools WITHOUT shrinking the content */
/* Restore the Right Column Tools */
html body.skin-vector-2022 .vector-column-end {
html body.skin-vector-2022 .vector-column-end {
     display: block !important;
     display: block !important;
    visibility: visible !important;
     position: absolute !important;
     position: absolute !important; /* Floats the tools so they don't push the content */
     right: 0;
     right: 0;
     top: 150px;
     top: 150px;
Line 211: Line 220:
}
}


/* 3. FORCE CONTENT FULL-WIDTH for Sysop */
/* Full-width content for Sysop */
html body.skin-vector-2022 .mw-content-container {
html body.skin-vector-2022 .mw-content-container {
     max-width: none !important;
     max-width: none !important;
     margin-right: 0 !important; /* Removes the "squeeze" */
     margin-right: 0 !important;
}
}
</pre>
</pre>


= Testing =
== Testing and Known Limitations ==
 
Preliminary testing shows:
 
* Anonymous users and regular users cannot reach dangerous pages through navigation 
* PageForms works correctly despite namespace restrictions 
* Sysop retains full interface access 


This configuration went to preliminary tests demonstrated satisfaction: no possible links in and around the pages Anonymous and Users should have access to. Of course if one knows the MediaWiki structure and how to access particular pages he or she might view configuration files. Trying to avoid this was very problematic and tries to do so were abandoned.
=== Known Limitations ===
* Anonymous users still see the top toolbar in Main (to be refined later) 
* Hardcoded sidebar paths must be updated if URL structure changes 
* MediaWiki cannot fully hide configuration pages from knowledgeable users 
* Lockdown cannot invert the permission model 


As we go along with defining more pages in Dashboard, we will experiment if the actual situation is acceptable or not. This means that this configuration is certainly not final. For example, the  top bar is gone in the Dashboard namespace for users, but is not gone for anonymous users in the Main namespace. This should certainly be possible, but will be finetuned later.
=== Future Work ===
* Remove top toolbar for anonymous users in Main
* Evaluate whether Dashboard needs further simplification 
* Test new namespaces as they are added 
* Revisit Cargo permissions once data volume grows

Revision as of 16:31, 13 February 2026

Final Configuration: Clutter Reduction and Protection

Document revision: 2026-02-13 by Mngr

Purpose and Philosophy

This MediaWiki installation supports a historical heritage project used primarily by senior researchers (mostly 70+). Their workflow is simple, and their expectations are shaped by historical research habits rather than IT experience. The system must therefore be:

  • As closed as reasonably possible
  • Predictable and stable
  • Minimal in clutter
  • Dark‑mode by default
  • Safe against accidental clicks

MediaWiki’s default philosophy is openness. After three days of experimentation, it became clear that a fully closed system is not feasible without brittle hacks. Instead, this configuration aims for a stable, predictable, minimally exposed environment that still respects MediaWiki’s architecture.

Dark mode is essential. Only Vector‑2022 provides a reliable dark mode, so the system standardizes on this skin. Attempts to use Minerva failed due to lack of dark mode support.

All data entry is performed through PageForms, and direct access to data namespaces is intentionally blocked. This ensures that users interact only with structured forms, not raw pages.

User Roles and Workflow

User Types

  • Anonymous visitors
Can read only the final public documents in the Main namespace
Should see no MediaWiki clutter
  • Club Members (users)
Can create and edit research drafts
Can enter data only through the Dashboard (PageForms)
Cannot access system areas or data namespaces directly
  • Sysop
Full administrative and interface control
Sees the full MediaWiki interface

Workflow Overview

Anonymous → Main (read-only)

Users → Dashboard (data entry via PageForms)
      → Research (drafting and reviewing)
      → No direct access to data namespaces

Sysop → All namespaces + interface

Publishing Flow

  1. Users introduce and document data via Dashboard forms.
  2. Users create and refine publication pages in Research.
  3. Once validated, pages are copied to Main for public access.
  4. Optionally, content may be exported to Wikipedia.

Configuring the Skin

# =================================================
# SKIN & INTERFACE
# =================================================
wfLoadSkin( 'Vector' );
$wgDefaultSkin = "vector-2022";

# Enable native dark mode
$wgVectorNightMode = [
    'beta' => true,
    'logged_in' => true,
    'logged_out' => true,
];

# Force dark mode for all users
$wgDefaultUserOptions['vector-theme'] = 'night';

Protection Model

MediaWiki cannot be inverted into a “deny everything, allow selectively” model. Lockdown adds restrictions, but it cannot:

  • override global permissions
  • grant permissions
  • create a deny‑by‑default environment

Therefore, the configuration below uses global permissions, namespace protection, and CSS‑based interface reduction.

Global Permissions

# Anonymous
$wgGroupPermissions['*']['read']          = true;
$wgGroupPermissions['*']['edit']          = false;
$wgGroupPermissions['*']['createaccount'] = false;

# Users
$wgGroupPermissions['user']['read']       = true;
$wgGroupPermissions['user']['edit']       = true;
$wgGroupPermissions['user']['upload']     = false;

# Sysop
$wgGroupPermissions['sysop']['editinterface'] = true;
$wgGroupPermissions['sysop']['upload']        = true;

Namespace Protection (Consolidated)

$wgNamespaceProtection[NS_MAIN]      = [ 'protect' ];        # Public library
$wgNamespaceProtection[NS_ICT]       = [ 'editinterface' ];  # Technical docs
$wgNamespaceProtection[NS_DASHBOARD] = [ 'editinterface' ];  # App layout

Content Namespaces

$wgContentNamespaces = [
    NS_MAIN, NS_RESEARCH, NS_ICT, NS_DASHBOARD,
    NS_CHAPTER, NS_PLACE, NS_ORGANISATION,
    NS_PERSON, NS_HERITAGE, NS_ASSET
];

$wgNamespacesWithSubpages[NS_DASHBOARD] = true;

A custom sidebar is injected for all non‑sysop users. This avoids exposing MediaWiki’s default navigation.

Important note for successors: This uses hardcoded paths. If $wgArticlePath or namespace names change, the sidebar must be updated.

$wgHooks['SidebarBeforeOutput'][] = function ( $skin, &$sidebar ) {
    $user = $skin->getUser();

    if ( !$user->isAllowed( 'editinterface' ) ) {
        $sidebar = [
            'Project Navigation' => [
                [ 'text' => 'Dashboard',      'href' => '/Dashboard:Main' ],
                [ 'text' => 'Research Area',  'href' => '/Research:Main' ],
            ],
            'Account' => [
                [ 'text' => 'Logout', 'href' => '/Special:UserLogout' ]
            ]
        ];
    }
    return true;
};

Cargo Hardening

$wgGroupPermissions['user']['runcargoqueries'] = false;
$wgGroupPermissions['user']['recreatecargodata'] = false;

Upload Restrictions

$wgGroupPermissions['user']['upload']        = false;
$wgGroupPermissions['user']['reupload']      = false;
$wgGroupPermissions['user']['reupload-own']  = false;

$wgGroupPermissions['sysop']['upload']       = true;
$wgGroupPermissions['sysop']['reupload']     = true;
$wgGroupPermissions['sysop']['reupload-own'] = true;

Optional Hardening

$wgNonincludableNamespaces[] = NS_ICT;

# Avoid login redirect bug
$wgRedirectOnLogin = "Hoofdpagina";

Interface Clutter Reduction (CSS)

User View (MediaWiki:Group-user.css)

/* Hide Top Bar & Right Column for Users in Dashboard & Main */
.ns-3020 .vector-page-toolbar, 
.ns-0 .vector-page-toolbar,
.ns-3020 .vector-column-end, 
.ns-0 .vector-column-end {
    display: none !important;
}

/* Reclaim space for full-width layout */
.ns-3020 .mw-content-container, 
.ns-0 .mw-content-container {
    max-width: none !important;
}

/* Ensure Form Buttons are NEVER hidden */
.mw-body-content .mw-ui-button, 
.mw-body-content .pfForm {
    display: inline-block !important;
    visibility: visible !important;
}

Sysop View (MediaWiki:Group-sysop.css)

/* Restore the Top Toolbar */
html body.skin-vector-2022 .vector-page-toolbar {
    display: flex !important;
}

/* Restore the Right Column Tools */
html body.skin-vector-2022 .vector-column-end {
    display: block !important;
    position: absolute !important;
    right: 0;
    top: 150px;
    z-index: 100;
}

/* Full-width content for Sysop */
html body.skin-vector-2022 .mw-content-container {
    max-width: none !important;
    margin-right: 0 !important;
}

Testing and Known Limitations

Preliminary testing shows:

  • Anonymous users and regular users cannot reach dangerous pages through navigation
  • PageForms works correctly despite namespace restrictions
  • Sysop retains full interface access

Known Limitations

  • Anonymous users still see the top toolbar in Main (to be refined later)
  • Hardcoded sidebar paths must be updated if URL structure changes
  • MediaWiki cannot fully hide configuration pages from knowledgeable users
  • Lockdown cannot invert the permission model

Future Work

  • Remove top toolbar for anonymous users in Main
  • Evaluate whether Dashboard needs further simplification
  • Test new namespaces as they are added
  • Revisit Cargo permissions once data volume grows