{ if (!isset($this->capabilities[$cap])) { return []; } return $this->capabilities[$cap]['roles']; } /** * Get capability users * * @param string $cap capability * * @return int[] */ public function getCapUsers($cap) { if (!isset($this->capabilities[$cap])) { return []; } return $this->capabilities[$cap]['users']; } /** * Check if capabilities are the default ones * * @return bool true if default false otherwise */ public function isDefault() { return $this->capabilities == self::getDefaultCaps(); } /** * Check if cababilitise have users capabilities set * * @return bool true if users capabilities are set false otherwise */ public function hasUsersCapabilities() { foreach ($this->capabilities as $cap => $data) { if (count($data['users']) > 0) { return true; } } return false; } /** * Reset default capabilities * * @return void */ public function reset() { $this->removeAll(); $this->capabilities = self::getDefaultCaps(); $this->save(); } /** * Remoe all capabilities * * @return bool true on success false otherwise */ private function removeAll() { foreach ($this->capabilities as $cap => $data) { foreach ($data['roles'] as $role) { $role = get_role($role); if ($role) { $role->remove_cap($cap); } } foreach ($data['users'] as $user) { $user = get_user_by('id', $user); if ($user) { $user->remove_cap($cap); } } } return delete_option(self::OPTION_KEY); } /** * Capabilities hard reset, check all users and roles and remove all capabilities * * @return bool */ public function hardReset() { try { $ids = get_users(['fields' => 'ID']); $capList = self::getCapsList(); foreach ($ids as $id) { $user = get_user_by('id', $id); foreach ($capList as $cap) { $user->remove_cap($cap); } } foreach (get_editable_roles() as $role => $info) { $role = get_role($role); foreach ($capList as $cap) { $role->remove_cap($cap); } } delete_option(self::OPTION_KEY); $this->capabilities = self::getDefaultCaps(); return $this->save(); } catch (Exception $e) { DUP_PRO_Log::trace('Capabilites hard reset failed'); } return false; } /** * Check if current user have the capability * Accept muiltiple capabilities, if one of them is true return true * * @param string $cap capability * @param bool $thow throw exception if the user don't have the capability * * @return bool return true if the user have the capability or throw an exception */ public static function can($cap, $thow = true) { /** * @var string[] $super_admins (array) An array of user IDs that should be granted super admin privileges (multisite). * This global is only set by the site owner (e.g., in wp-config.php), * and contains an array of IDs of users who should have super admin privileges. * If set it will override the list of super admins in the database. * @see https://codex.wordpress.org/Global_Variables */ global $super_admins; $originalSuperAdmins = $super_admins; $restoreSuperAdmins = false; try { $user = wp_get_current_user(); if (strpos($cap, self::CAP_PREFIX) === 0 && is_multisite()) { if (!is_super_admin()) { throw new Exception('User is not super admin'); } if (!in_array(self::ROLE_SUPERADMIN, self::getInstance()->capabilities[$cap]['roles'])) { // The default super_admin users have all the capabilities so // it temporarily removes the current user from the super admins to do the check $tempSuperAdmins = get_super_admins(); if (($key = array_search($user->user_login, $tempSuperAdmins)) !== false) { unset($tempSuperAdmins[$key]); $super_admins = array_values($tempSuperAdmins); $restoreSuperAdmins = true; } } } if (!$user->has_cap($cap)) { throw new Exception('User don\'t have the capability'); } } catch (Exception $e) { if ($thow) { DUP_PRO_Log::trace('SECUTIRY ISSUE: USER ID ' . get_current_user_id() . ' cap: ' . $cap); DUP_PRO_Log::trace(SnapLog::getTextException($e)); throw new Exception('Security issue.'); } else { return false; } } finally { if ($restoreSuperAdmins) { $super_admins = $originalSuperAdmins; } } return true; } /** * Get selectable roles * * @return array */ public static function getSelectableRoles() { if (is_multisite()) { return [self::ROLE_SUPERADMIN => 'Super Admin']; } else { $result = []; foreach (get_editable_roles() as $role => $roleInfo) { $result[$role] = $roleInfo['name']; } return $result; } } /** * Get capabilities list * * @return string[] */ public static function getCapsList() { static $list = null; if (is_null($list)) { $list = array_keys(self::getDefaultCaps()); } return $list; } /** * Get default capabilities * * @return array */ public static function getDefaultCaps() { $defRoles = (is_multisite() ? [self::ROLE_SUPERADMIN] : ['administrator']); return [ self::CAP_BASIC => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_CREATE => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_SCHEDULE => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_STORAGE => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_BACKUP_RESTORE => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_IMPORT => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_EXPORT => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_SETTINGS => [ 'roles' => $defRoles, 'users' => [], ], self::CAP_LICENSE => [ 'roles' => $defRoles, 'users' => [], ], ]; } /** * Get capabilities info * * @return array */ public static function getCapsInfo() { return [ self::CAP_BASIC => [ 'parent' => '', 'label' => __('Package Read', 'duplicator-pro'), 'desc' => __( 'The capability to read the list of packages and their characteristics.', 'duplicator-pro' ) . ' ' . __( 'Without this capability, Duplicator is not visible. This is the basis of all the other capabilities listed below.', 'duplicator-pro' ), ], self::CAP_CREATE => [ 'parent' => self::CAP_BASIC, 'label' => __('Package Create', 'duplicator-pro'), 'desc' => __( 'The capability to create and delete packages.', 'duplicator-pro' ), ], self::CAP_SCHEDULE => [ 'parent' => self::CAP_CREATE, 'label' => __('Manage Schedules', 'duplicator-pro'), 'desc' => __( 'The capability to manage package schedules.', 'duplicator-pro' ), ], self::CAP_STORAGE => [ 'parent' => self::CAP_CREATE, 'label' => __('Manage Storage', 'duplicator-pro'), 'desc' => __( 'The capability to create and modify storage. Those with the "Package Create" capability can select existing storage but cannot edit it', 'duplicator-pro' ), ], self::CAP_BACKUP_RESTORE => [ 'parent' => self::CAP_BASIC, 'label' => __('Restore Backup', 'duplicator-pro'), 'desc' => __( 'The capability to set up and execute a recovery point', 'duplicator-pro' ), ], self::CAP_IMPORT => [ 'parent' => self::CAP_BACKUP_RESTORE, 'label' => __('Package Import', 'duplicator-pro'), 'desc' => __( 'The capability to import a package and overwrite the current site.', 'duplicator-pro' ), ], self::CAP_EXPORT => [ 'parent' => self::CAP_BASIC, 'label' => __('Package Export', 'duplicator-pro'), 'desc' => __( 'The capability to download existing packages.', 'duplicator-pro' ), ], self::CAP_SETTINGS => [ 'parent' => self::CAP_BASIC, 'label' => __('Manage Settings', 'duplicator-pro'), 'desc' => __( 'The capability to change settings.', 'duplicator-pro' ), ], self::CAP_LICENSE => [ 'parent' => self::CAP_SETTINGS, 'label' => __('Manage License Settings', 'duplicator-pro'), 'desc' => __( 'The capability to change the license settings.', 'duplicator-pro' ), ], ]; } }