security: restrict plugin settings to master user + rename Gitea to MokoGitea
- Non-master users blocked from editing MokoWaaS plugin config - isOurPlugin() helper checks extension_id against our plugin - Blocks both edit view and save task for non-master users - Renamed bare 'Gitea' references to 'MokoGitea' in docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,5 +38,5 @@ This is a Joomla extension. Key directories:
|
||||
- **Attribution**: use `Authored-by: Moko Consulting` in commits
|
||||
- **Branch strategy**: develop on `dev`, merge to `main` for release
|
||||
- **Minification**: handled at build time (CI) and runtime (MokoMinifyHelper for Joomla templates)
|
||||
- **Wiki**: documentation lives in the Gitea wiki, not in `docs/` files
|
||||
- **Wiki**: documentation lives in the MokoGitea wiki, not in `docs/` files
|
||||
- **Standards**: this repo follows [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)
|
||||
|
||||
@@ -52,7 +52,7 @@ This ensures Joomla sites on any "Minimum Stability" setting always see the late
|
||||
|
||||
### Sync to Main
|
||||
|
||||
Since Joomla sites read `updates.xml` from the `main` branch, the `update-server.yml` workflow **syncs `updates.xml` to `main` via the Gitea API** after building on non-main branches. This ensures pre-release channel entries are visible to sites checking for updates without requiring a PR merge to main.
|
||||
Since Joomla sites read `updates.xml` from the `main` branch, the `update-server.yml` workflow **syncs `updates.xml` to `main` via the MokoGitea API** after building on non-main branches. This ensures pre-release channel entries are visible to sites checking for updates without requiring a PR merge to main.
|
||||
|
||||
### Generated XML Structure
|
||||
|
||||
@@ -120,7 +120,7 @@ dev → [alpha] → [beta] → rc → version/XX → main → dev
|
||||
optional optional (integration) (production) (feedback)
|
||||
```
|
||||
|
||||
1. **Development** (`dev` or `dev/**`): `updates.xml` with `<tag>development</tag>`, download points to Gitea release ZIP
|
||||
1. **Development** (`dev` or `dev/**`): `updates.xml` with `<tag>development</tag>`, download points to MokoGitea release ZIP
|
||||
2. **Alpha** (`alpha/**`): `updates.xml` with `<tag>alpha</tag>`, cascades to development channel
|
||||
3. **Beta** (`beta/**`): `updates.xml` with `<tag>beta</tag>`, cascades to alpha + development channels
|
||||
4. **Release Candidate** (`rc/**`): `updates.xml` with `<tag>rc</tag>`, cascades to beta + alpha + development channels
|
||||
|
||||
@@ -1681,6 +1681,36 @@ class MokoWaaS extends CMSPlugin
|
||||
$view = $input->get('view', '');
|
||||
$task = $input->get('task', '');
|
||||
|
||||
// MokoWaaS plugin settings — master user only
|
||||
if ($option === 'com_plugins'
|
||||
&& !$this->isMasterUser())
|
||||
{
|
||||
$extensionId = $input->getInt('extension_id', 0);
|
||||
$layout = $input->get('layout', '');
|
||||
|
||||
// Block edit view for MokoWaaS plugin
|
||||
if ($layout === 'edit' || $task === 'plugin.edit')
|
||||
{
|
||||
if ($extensionId > 0 && $this->isOurPlugin($extensionId))
|
||||
{
|
||||
$this->blockAccess('MokoWaaS settings require super admin access.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Block save attempts
|
||||
if ($task === 'plugin.apply' || $task === 'plugin.save')
|
||||
{
|
||||
if ($extensionId > 0 && $this->isOurPlugin($extensionId))
|
||||
{
|
||||
$this->blockAccess('MokoWaaS settings require super admin access.');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable install-from-URL for ALL users (safety net)
|
||||
if ($this->params->get('disable_install_url', 1)
|
||||
&& $option === 'com_installer'
|
||||
@@ -1792,6 +1822,32 @@ class MokoWaaS extends CMSPlugin
|
||||
return $user->username === $masterUsername;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an extension ID belongs to the MokoWaaS plugin.
|
||||
*
|
||||
* @param int $extensionId Extension ID to check
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 02.01.38
|
||||
*/
|
||||
protected function isOurPlugin(int $extensionId): bool
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('extension_id') . ' = ' . $extensionId)
|
||||
->where($db->quoteName('element') . ' = '
|
||||
. $db->quote('mokowaas'))
|
||||
->where($db->quoteName('folder') . ' = '
|
||||
. $db->quote('system'));
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
return (int) $db->loadResult() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the list of components to hide from admin menu.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user