feat(users): govern profiles and access
Normalize fixed profile fields, profile actions, and the five-column capability matrix for comments, uploads, and downloads.
This commit is contained in:
@@ -91,6 +91,15 @@ class Download {
|
||||
}
|
||||
|
||||
public function check_rest_nonce(\WP_REST_Request $request) {
|
||||
// The capability matrix can explicitly allow resource downloads for
|
||||
// everyone. A WordPress REST nonce only exists for authenticated
|
||||
// sessions, so requiring one from visitors would make the "all"
|
||||
// column ineffective. Anonymous requests still pass the unified
|
||||
// download gate (capability, payment and captcha) in rest_request().
|
||||
if (get_current_user_id() <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$nonce = $request->get_header('x-wp-nonce');
|
||||
if (!$nonce) {
|
||||
return new \WP_Error('aksrt_rest_no_nonce', __('缺少安全令牌', 'aksrt'), ['status' => 403]);
|
||||
@@ -109,7 +118,6 @@ class Download {
|
||||
}
|
||||
|
||||
$meta = function_exists('aksrt_get_download_box_meta') ? aksrt_get_download_box_meta($post) : [];
|
||||
$paid_settings = \AKSRT\Settings\Settings::get_paid_content_settings();
|
||||
$cost = aksrt_resource_download_cost($post);
|
||||
$uid = get_current_user_id();
|
||||
$priced = function_exists('aksrt_get_user_pay_price') ? aksrt_get_user_pay_price($post, $uid) : null;
|
||||
@@ -122,10 +130,7 @@ class Download {
|
||||
? Visibility::get_post_access_state($post, $uid)
|
||||
: [];
|
||||
|
||||
$need_captcha = !empty($paid_settings['download_captcha']) || !empty($meta['require_captcha']);
|
||||
if ($need_captcha && function_exists('aksrt_is_captcha_enabled_for') && !aksrt_is_captcha_enabled_for('download')) {
|
||||
$need_captcha = false;
|
||||
}
|
||||
$need_captcha = function_exists('aksrt_is_captcha_enabled_for') && aksrt_is_captcha_enabled_for('download');
|
||||
|
||||
return new \WP_REST_Response([
|
||||
'post_id' => $post_id,
|
||||
@@ -134,7 +139,7 @@ class Download {
|
||||
'pay_modo' => $pay_modo,
|
||||
'pay_limit' => (int) ($meta['pay_limit'] ?? 0),
|
||||
'cost' => $cost,
|
||||
'require_login' => !empty($paid_settings['download_login']) || !empty($meta['require_login']) || (!empty($paid_settings['free_logged_show']) && $cost <= 0 && $display_price <= 0),
|
||||
'require_login' => !empty($access['need_login']),
|
||||
'require_captcha' => $need_captcha,
|
||||
'logged_in' => $uid > 0,
|
||||
'balance' => $uid > 0 && class_exists('\AKSRT\Credits\Credits') ? \AKSRT\Credits\Credits::balance($uid) : 0,
|
||||
@@ -181,7 +186,6 @@ class Download {
|
||||
$gate = aksrt_can_download($post);
|
||||
if (is_wp_error($gate)) return $gate;
|
||||
|
||||
$paid_settings = \AKSRT\Settings\Settings::get_paid_content_settings();
|
||||
$uid = get_current_user_id();
|
||||
$cost = aksrt_resource_download_cost($post);
|
||||
|
||||
@@ -193,8 +197,7 @@ class Download {
|
||||
}
|
||||
}
|
||||
|
||||
$need_captcha = !empty($paid_settings['download_captcha']) || !empty($meta['require_captcha']);
|
||||
// 下载双开关:cms_features.download_captcha(或单资源强制)且场景未停用。
|
||||
$need_captcha = function_exists('aksrt_is_captcha_enabled_for') && aksrt_is_captcha_enabled_for('download');
|
||||
if ($need_captcha && function_exists('aksrt_require_captcha')) {
|
||||
$cap_payload = isset($params['captcha']) && is_array($params['captcha']) ? $params['captcha'] : [];
|
||||
// 场景未启用时 require 直接放行;启用时强制校验 token。
|
||||
|
||||
+14
-28
@@ -47,14 +47,6 @@ class Visibility {
|
||||
: (($pay_modo === 'points')
|
||||
? (float) ($pay_meta['points_price'] ?? 0)
|
||||
: (float) ($pay_meta['price'] ?? 0));
|
||||
$paid_settings = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_paid_content_settings()
|
||||
: [
|
||||
'download_login' => true,
|
||||
'download_credit' => true,
|
||||
'download_captcha' => false,
|
||||
];
|
||||
|
||||
$state = [
|
||||
'post_id' => $resource_post instanceof \WP_Post ? (int) $resource_post->ID : 0,
|
||||
'pay_type' => $pay_type,
|
||||
@@ -134,12 +126,13 @@ class Visibility {
|
||||
if ($allowed_member && $price <= 0) {
|
||||
$download_cost = 0;
|
||||
}
|
||||
$can_download = function_exists('aksrt_user_can') && aksrt_user_can('resource_download', $uid, (int) $resource_post->ID);
|
||||
$state['download_cost'] = max(0, $download_cost);
|
||||
$state['need_login'] = $uid <= 0;
|
||||
$state['need_login'] = !$can_download && $uid <= 0;
|
||||
$state['need_purchase'] = $allowed_member && $price > 0 && !$has_paid_order;
|
||||
$state['has_paid_access'] = $allowed_member && ($has_paid_order || $price <= 0);
|
||||
$state['can_view'] = true;
|
||||
$state['can_download'] = $allowed_member && ($uid > 0) && ($has_paid_order || $price <= 0);
|
||||
$state['can_download'] = $can_download && $allowed_member && ($has_paid_order || $price <= 0);
|
||||
if (!$allowed_member) {
|
||||
$state['can_download'] = false;
|
||||
$state['has_paid_access'] = false;
|
||||
@@ -172,16 +165,14 @@ class Visibility {
|
||||
}
|
||||
$state['download_cost'] = max(0, $download_cost);
|
||||
|
||||
$free_logged_show = !empty($paid_settings['free_logged_show']);
|
||||
$state['need_login'] = !empty($paid_settings['download_login'])
|
||||
|| !empty($pay_meta['require_login'])
|
||||
|| ($free_logged_show && $price <= 0);
|
||||
$state['require_captcha'] = !empty($paid_settings['download_captcha']) || !empty($pay_meta['require_captcha']);
|
||||
$can_download = function_exists('aksrt_user_can') && aksrt_user_can('resource_download', $uid, (int) $resource_post->ID);
|
||||
$state['need_login'] = !$can_download && $uid <= 0;
|
||||
$state['require_captcha'] = function_exists('aksrt_is_captcha_enabled_for') && aksrt_is_captcha_enabled_for('download');
|
||||
|
||||
$state['need_purchase'] = !$has_paid_order && $price > 0;
|
||||
$state['has_paid_access'] = $has_paid_order || $price <= 0 || $has_free_access;
|
||||
$state['can_view'] = true;
|
||||
$state['can_download'] = (!$state['need_login'] || $uid > 0) && ($has_paid_order || $price <= 0);
|
||||
$state['can_download'] = $can_download && ($has_paid_order || $price <= 0);
|
||||
|
||||
return $state;
|
||||
}
|
||||
@@ -227,6 +218,13 @@ class Visibility {
|
||||
$state = self::get_post_access_state($resource_post, $user_id);
|
||||
$uid = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
|
||||
if (!function_exists('aksrt_user_can') || !aksrt_user_can('resource_download', $uid, (int) $resource_post->ID)) {
|
||||
return new \WP_Error('aksrt_download_forbidden', __('当前账号没有下载资源的权限。', 'aksrt'), [
|
||||
'status' => $uid > 0 ? 403 : 401,
|
||||
'login_url' => wp_login_url(get_permalink($resource_post)),
|
||||
]);
|
||||
}
|
||||
|
||||
if (($state['pay_type'] ?? '') !== \AKSRT\Core\DomainModel::PAY_TYPE_DOWNLOAD) {
|
||||
return new \WP_Error('aksrt_not_downloadable', __('该内容未启用下载能力。', 'aksrt'));
|
||||
}
|
||||
@@ -238,19 +236,7 @@ class Visibility {
|
||||
]);
|
||||
}
|
||||
|
||||
// Free download + pay_free_logged_show (belt-and-suspenders with state.need_login).
|
||||
$cost = (int) ($state['download_cost'] ?? 0);
|
||||
$paid_settings = class_exists('\AKSRT\Settings\Settings')
|
||||
? \AKSRT\Settings\Settings::get_paid_content_settings()
|
||||
: ['download_credit' => true, 'free_logged_show' => false];
|
||||
|
||||
if ($cost <= 0 && !empty($paid_settings['free_logged_show']) && $uid <= 0) {
|
||||
return new \WP_Error('aksrt_need_login', __('免费资源,请登录后下载。', 'aksrt'), [
|
||||
'status' => 401,
|
||||
'login_url' => wp_login_url(get_permalink($resource_post)),
|
||||
]);
|
||||
}
|
||||
|
||||
// Member-only (pay_limit).
|
||||
if (!empty($state['need_vip']) && empty($state['has_paid_access']) && empty($state['can_download'])) {
|
||||
$need_level = (int) ($state['pay_limit'] ?? 1);
|
||||
|
||||
Reference in New Issue
Block a user