Federated Wiki - FarmManager Plugin
Plugin for managing a wiki instance as a farm of multiple wiki sites.
The focus of this plugin is to allow for programmatic, centralized management of a wiki farm by a farm administrator. It is intended to supersede wiki-plugin-register by providing administrative oversight rather than self-service registration.
Design Philosophy
- Admin-Focused: All features are designed to be used by a farm administrator. Access will be restricted to admin users.
- JSON API: The server-side component will expose a well-defined API for managing sites. This ensures the API is predictable and can be used by other tools, not just our web interface.
- Clear Separation: The backend (API) and frontend (web interface) will be clearly separated. The web interface will be a client of the API.
- Safety: Destructive operations (like deleting a site) are non-destructive by default and require confirmation.
API Design
Authentication for all endpoints will be handled by a middleware that checks app.securityhandler.isAdmin(req).
Endpoints
-
GET /plugin/farmmanager/sites- Action: List all wiki sites in the farm.
- Response Body: An array of site objects.
[{ "name": "site1.myfarm.com", "owner": "Alice", "pages": 12, "status": "active" }, ...]
-
POST /plugin/farmmanager/sites- Action: Create a new wiki site.
- Request Body:
{ "domain": "newsite", "owner": "Bob" } - Response Body: The new site object.
-
GET /plugin/farmmanager/sites/:domain- Action: Get detailed information for a single site.
- URL Parameter:
:domainis the full domain of the site (e.g.,site1.myfarm.com). - Response Body: A single site object.
-
PATCH /plugin/farmmanager/sites/:domain- Action: Partially update a site's properties (preserves unspecified fields).
- Request Body:
{ "owner": {"name": "Carol", ...} }or{ "status": "active" }or both - Status values:
active,readonly, orinactive(see Site states). - Response Body: The updated site object.
Site states
A site's status (stored in <site>/status.json and surfaced on every site object) is one of:
active— normal, fully editable site.readonly— pages are still served and readable, but edits, forks, and new pages are blocked. Reversible:PATCHthe status back toactiveto restore editing. The transition is idempotent — re-applyingreadonlykeeps the originalreadOnlyAttimestamp, and returning toactiveclears it.inactive— soft-deleted / deactivated (set byDELETEwithouthard=true).
How read-only is enforced (plugin-only): wiki-server gates every content-mutating route — edit/add/remove/move/create/fork via PUT /page/:slug/action, page DELETE, favicon upload, and recycler deletes — behind a single securityhandler.isAuthorized(req) check, while public page reads never call it. On startup the plugin wraps that handler so it denies authorization whenever the current site's status.json reads readonly, blocking all writes without touching reads and without modifying wiki-server. isAdmin is left intact, so the farm-manager API can still flip the flag back. In farm mode each site has its own server instance; the flag is re-read from disk per check, so a status change made from the admin site takes effect immediately.
On-site indicator (plugin-only): the wiki client always loads /theme/style.css (served from <site>/status/theme/style.css). When a site goes read-only the plugin writes a small, clearly-delimited banner rule into that stylesheet, and removes only that block when the site is reactivated — any owner-authored theme CSS in the file is preserved. This needs no changes to wiki-client or the security module. Because CSS cannot read the per-request isOwner flag, the banner is shown to every visitor of a read-only site, not only the owner. (An owner-only on-site message would require client JS reading isOwner, which means touching the auth provider's client code; the banner above is the robust plugin-only option.)
DELETE /plugin/farmmanager/sites/:domain- Action: Deactivate a wiki site (soft delete). Adds a
status.jsonfile marking the site as inactive. - Query Parameters:
hard=true- Permanently delete the site directory and all its contents (irreversible).
- Response Body:
{ "status": "ok", "message": "Site site1.myfarm.com deactivated." }
- Action: Deactivate a wiki site (soft delete). Adds a
Web Interface Design
The client component (farmmanager plugin item) renders an admin dashboard inside a wiki page. It lists every site in the farm with its owner, page count, and a status badge (active / read-only / inactive), and gives each site a one-click action to flip it between editable and read-only (and to reactivate a deactivated site). It calls the JSON API above, so it inherits the same admin-only access control; non-admin or non-farm responses are surfaced as an inline message. Add it to a page like any other plugin item (a farmmanager story item), ideally on your designated admin site.
Development Plan
We can build this in phases.
-
Phase 1: Backend API
- Setup: Create the basic
server/server.jsfile andadminsecurity middleware. - List Sites (Read): Implement the
GET /sitesendpoint. This will involve scanning the data directory for site folders and reading theirowner.jsonandstatus.json. - Create Site: Implement the
POST /sitesendpoint. This can borrow logic fromwiki-plugin-registerbut will be wrapped in admin security. - Deactivate Site: Implement the
DELETE /sites/:domainendpoint. This will involve creating or updating astatus.jsonfile in the site's directory. - Update Site: Implement the
PUT /sites/:domainendpoint to change theowner.json.
- Setup: Create the basic
-
Phase 2: Frontend UI
- TBD after the backend API is stable.
Roadmap
- Search/Filter: Add a search or filter feature to the UI for farms with many sites.
- UI Pattern Documentation: Create documentation for the pattern of building plugins that render as components within a wiki page.
Architecture Notes
Site-Level Plugin with Farm-Level Scope
This plugin follows the standard FedWiki plugin architecture, which means it is loaded per-site when you navigate to a specific site in the farm. However, its purpose is to manage farm-level resources (all sites in the farm).
What this means in practice:
-
Access Pattern: You must first navigate to a specific site (e.g.,
http://localhost) to load the plugin. Once loaded, the API endpoints are available and can manage all sites in the farm. -
Admin Site Approach: In practice, designate one site as your "admin site" (e.g.,
localhostoradmin.example.com) and always access the farm management API through that site. -
Data Directory Resolution: The plugin receives
argv.datapointing to the current site's directory (e.g.,/data-farm/localhost). It usespath.resolve(argv.data, '..')to access the parent farm directory and enumerate all sites. -
Security Context: Admin authentication and authorization are tied to the site you're accessing the API from, which aligns with FedWiki's per-site security model.
This is consistent with how other farm-management plugins (like wiki-plugin-register) operate in the FedWiki ecosystem.
Build
npm install
npm run build
License
MIT