| @@ -290,8 +290,17 @@ | ||
| 290 | 290 | |
| 291 | 291 | /** |
| 292 | 292 | * `desktop-mode/get-post` permission callback. |
| 293 | 293 | * |
| 294 | + * `read_post` decides visibility (published / private / draft) and | |
| 295 | + * never the post password — WordPress splits the two deliberately, so | |
| 296 | + * a plain `read_post` check would hand a Subscriber the raw body of a | |
| 297 | + * password-protected post. Mirror Core: a sealed post stays sealed | |
| 298 | + * unless the caller can edit it (the same escape hatch | |
| 299 | + * `WP_REST_Posts_Controller::check_password_required()` grants), and | |
| 300 | + * because this ability returns RAW `post_content` there is no empty | |
| 301 | + * rendered field to fall back to — the only safe answer is to refuse. | |
| 302 | + * | |
| 294 | 303 | * @param array $args Input args. |
| 295 | 304 | * @return bool |
| 296 | 305 | */ |
| 297 | 306 | function openstation_agents_ability_get_post_can( $args ) { |
| @@ -299,9 +308,16 @@ | ||
| 299 | 308 | $post_id = isset( $args['post_id'] ) ? (int) $args['post_id'] : 0; |
| 300 | 309 | if ( $post_id <= 0 ) { |
| 301 | 310 | return false; |
| 302 | 311 | } |
| 303 | - return current_user_can( 'read_post', $post_id ); | |
| 312 | + if ( ! current_user_can( 'read_post', $post_id ) ) { | |
| 313 | + return false; | |
| 314 | + } | |
| 315 | + $post = get_post( $post_id ); | |
| 316 | + if ( $post instanceof WP_Post && post_password_required( $post ) && ! current_user_can( 'edit_post', $post_id ) ) { | |
| 317 | + return false; | |
| 318 | + } | |
| 319 | + return true; | |
| 304 | 320 | } |
| 305 | 321 | |
| 306 | 322 | /** |
| 307 | 323 | * `desktop-mode/get-media` execute callback. |