modified: README.md modified: support-provisioning-portal/assets/portal.css modified: support-provisioning-portal/assets/portal.js modified: support-provisioning-portal/includes/class-spp-activator.php modified: support-provisioning-portal/includes/class-spp-admin-page.php modified: support-provisioning-portal/includes/class-spp-http-proxmox-client.php modified: support-provisioning-portal/includes/class-spp-mock-proxmox-client.php new file: support-provisioning-portal/includes/class-spp-permissions.php modified: support-provisioning-portal/includes/class-spp-plugin.php modified: support-provisioning-portal/includes/class-spp-repository.php modified: support-provisioning-portal/includes/class-spp-rest-controller.php modified: support-provisioning-portal/includes/class-spp-shortcode.php modified: support-provisioning-portal/includes/interface-spp-proxmox-client.php modified: support-provisioning-portal/support-provisioning-portal.php
182 lines
5.4 KiB
PHP
182 lines
5.4 KiB
PHP
<?php
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
final class SPP_Permissions
|
|
{
|
|
public const META_KEY = 'spp_permissions';
|
|
|
|
public const VIEW_PORTAL = 'view_portal';
|
|
public const CREATE_DEPLOYMENTS = 'create_deployments';
|
|
public const START_DEPLOYMENTS = 'start_deployments';
|
|
public const STOP_DEPLOYMENTS = 'stop_deployments';
|
|
public const PROLONG_DEPLOYMENTS = 'prolong_deployments';
|
|
public const REFRESH_DEPLOYMENT_IPS = 'refresh_deployment_ips';
|
|
public const DELETE_DEPLOYMENTS = 'delete_deployments';
|
|
public const MANAGE_ALL_DEPLOYMENTS = 'manage_all_deployments';
|
|
public const MANAGE_TEMPLATES = 'manage_templates';
|
|
public const MANAGE_SETTINGS = 'manage_settings';
|
|
public const MANAGE_PERMISSIONS = 'manage_permissions';
|
|
|
|
/**
|
|
* @return array<string, string>
|
|
*/
|
|
public static function definitions(): array
|
|
{
|
|
return [
|
|
self::VIEW_PORTAL => 'Open portal and view deployments',
|
|
self::CREATE_DEPLOYMENTS => 'Create deployments',
|
|
self::START_DEPLOYMENTS => 'Start deployments',
|
|
self::STOP_DEPLOYMENTS => 'Stop deployments',
|
|
self::PROLONG_DEPLOYMENTS => 'Prolong deployments',
|
|
self::REFRESH_DEPLOYMENT_IPS => 'Refresh IP addresses',
|
|
self::DELETE_DEPLOYMENTS => 'Delete deployments',
|
|
self::MANAGE_ALL_DEPLOYMENTS => 'View and manage all deployments',
|
|
self::MANAGE_TEMPLATES => 'Manage templates',
|
|
self::MANAGE_SETTINGS => 'Manage Proxmox settings and quotas',
|
|
self::MANAGE_PERMISSIONS => 'Manage user rights',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<string, array<int, string>>
|
|
*/
|
|
public static function groups(): array
|
|
{
|
|
return [
|
|
'Portal' => [
|
|
self::VIEW_PORTAL,
|
|
self::CREATE_DEPLOYMENTS,
|
|
],
|
|
'Lifecycle' => [
|
|
self::START_DEPLOYMENTS,
|
|
self::STOP_DEPLOYMENTS,
|
|
self::PROLONG_DEPLOYMENTS,
|
|
self::REFRESH_DEPLOYMENT_IPS,
|
|
self::DELETE_DEPLOYMENTS,
|
|
],
|
|
'Administration' => [
|
|
self::MANAGE_ALL_DEPLOYMENTS,
|
|
self::MANAGE_TEMPLATES,
|
|
self::MANAGE_SETTINGS,
|
|
self::MANAGE_PERMISSIONS,
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array<mixed> $permissions
|
|
* @return array<int, string>
|
|
*/
|
|
public static function sanitize_permissions(array $permissions): array
|
|
{
|
|
$valid = array_keys(self::definitions());
|
|
$selected = [];
|
|
|
|
foreach ($permissions as $permission) {
|
|
$permission = sanitize_key((string) $permission);
|
|
if (in_array($permission, $valid, true) && !in_array($permission, $selected, true)) {
|
|
$selected[] = $permission;
|
|
}
|
|
}
|
|
|
|
$portal_rights = array_diff($selected, [
|
|
self::VIEW_PORTAL,
|
|
self::MANAGE_TEMPLATES,
|
|
self::MANAGE_SETTINGS,
|
|
self::MANAGE_PERMISSIONS,
|
|
]);
|
|
|
|
if (!empty($portal_rights) && !in_array(self::VIEW_PORTAL, $selected, true)) {
|
|
$selected[] = self::VIEW_PORTAL;
|
|
}
|
|
|
|
return array_values(array_intersect($valid, $selected));
|
|
}
|
|
|
|
public function current_user_has(string $permission): bool
|
|
{
|
|
if (!array_key_exists($permission, self::definitions())) {
|
|
return false;
|
|
}
|
|
|
|
if ($this->user_has(get_current_user_id(), $permission)) {
|
|
return true;
|
|
}
|
|
|
|
return $this->has_bootstrap_access();
|
|
}
|
|
|
|
public function current_user_has_any(): bool
|
|
{
|
|
return !empty($this->current_user_permissions());
|
|
}
|
|
|
|
/**
|
|
* @return array<int, string>
|
|
*/
|
|
public function current_user_permissions(): array
|
|
{
|
|
if ($this->has_bootstrap_access()) {
|
|
return array_keys(self::definitions());
|
|
}
|
|
|
|
return $this->for_user(get_current_user_id());
|
|
}
|
|
|
|
public function user_has(int $user_id, string $permission): bool
|
|
{
|
|
if (!array_key_exists($permission, self::definitions())) {
|
|
return false;
|
|
}
|
|
|
|
return in_array($permission, $this->for_user($user_id), true);
|
|
}
|
|
|
|
/**
|
|
* @return array<int, string>
|
|
*/
|
|
public function for_user(int $user_id): array
|
|
{
|
|
if ($user_id < 1) {
|
|
return [];
|
|
}
|
|
|
|
$permissions = get_user_meta($user_id, self::META_KEY, true);
|
|
|
|
return is_array($permissions) ? self::sanitize_permissions($permissions) : [];
|
|
}
|
|
|
|
/**
|
|
* @return array<int, int>
|
|
*/
|
|
public function user_ids_with_permission(string $permission): array
|
|
{
|
|
if (!array_key_exists($permission, self::definitions())) {
|
|
return [];
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
$like = '%"' . $wpdb->esc_like($permission) . '"%';
|
|
$ids = $wpdb->get_col(
|
|
$wpdb->prepare(
|
|
"SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND meta_value LIKE %s",
|
|
self::META_KEY,
|
|
$like
|
|
)
|
|
);
|
|
|
|
return array_values(array_map('intval', is_array($ids) ? $ids : []));
|
|
}
|
|
|
|
private function has_bootstrap_access(): bool
|
|
{
|
|
return is_user_logged_in()
|
|
&& current_user_can('manage_options')
|
|
&& empty($this->user_ids_with_permission(self::MANAGE_PERMISSIONS));
|
|
}
|
|
}
|