From 0f2c94be77d586c5bb583c1c5a7ebb66cc9ab7f0 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 12 Jul 2024 10:41:26 +0200 Subject: [PATCH] Add: Permission checks to avoid 403 errors on non admin roles. (#63296) Co-authored-by: jorgefilipecosta Co-authored-by: Mamaduka --- .../edit-post/src/store/private-selectors.js | 9 +++- .../editor/src/components/blog-title/index.js | 9 +++- .../global-styles-provider/index.js | 51 ++++++++++++++----- .../src/components/post-card-panel/index.js | 8 ++- .../post-content-information/index.js | 8 ++- .../src/components/post-template/hooks.js | 10 +++- .../editor/src/components/post-url/panel.js | 9 +++- .../src/components/posts-per-page/index.js | 9 +++- .../src/components/site-discussion/index.js | 9 +++- 9 files changed, 96 insertions(+), 26 deletions(-) diff --git a/packages/edit-post/src/store/private-selectors.js b/packages/edit-post/src/store/private-selectors.js index be23227d54a19b..c151f935d68d50 100644 --- a/packages/edit-post/src/store/private-selectors.js +++ b/packages/edit-post/src/store/private-selectors.js @@ -12,8 +12,13 @@ export const getEditedPostTemplateId = createRegistrySelector( type: postType, slug, } = select( editorStore ).getCurrentPost(); - const { getSite, getEntityRecords } = select( coreStore ); - const siteSettings = getSite(); + const { getSite, getEntityRecords, canUser } = select( coreStore ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getSite() + : undefined; // First check if the current page is set as the posts page. const isPostsPage = +postId === siteSettings?.page_for_posts; if ( isPostsPage ) { diff --git a/packages/editor/src/components/blog-title/index.js b/packages/editor/src/components/blog-title/index.js index 4964ac3a0ec04d..1356edf9724e16 100644 --- a/packages/editor/src/components/blog-title/index.js +++ b/packages/editor/src/components/blog-title/index.js @@ -27,9 +27,14 @@ export default function BlogTitle() { const { editEntityRecord } = useDispatch( coreStore ); const { postsPageTitle, postsPageId, isTemplate, postSlug } = useSelect( ( select ) => { - const { getEntityRecord, getEditedEntityRecord } = + const { getEntityRecord, getEditedEntityRecord, canUser } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getEntityRecord( 'root', 'site' ) + : undefined; const _postsPageRecord = siteSettings?.page_for_posts ? getEditedEntityRecord( 'postType', diff --git a/packages/editor/src/components/global-styles-provider/index.js b/packages/editor/src/components/global-styles-provider/index.js index b7869e3413c3de..62e390cba25ae4 100644 --- a/packages/editor/src/components/global-styles-provider/index.js +++ b/packages/editor/src/components/global-styles-provider/index.js @@ -33,17 +33,30 @@ export function mergeBaseAndUserConfigs( base, user ) { function useGlobalStylesUserConfig() { const { globalStylesId, isReady, settings, styles, _links } = useSelect( ( select ) => { - const { getEditedEntityRecord, hasFinishedResolution } = - select( coreStore ); + const { + getEditedEntityRecord, + hasFinishedResolution, + getUser, + getCurrentUser, + } = select( coreStore ); const _globalStylesId = select( coreStore ).__experimentalGetCurrentGlobalStylesId(); - const record = _globalStylesId - ? getEditedEntityRecord( - 'root', - 'globalStyles', - _globalStylesId - ) - : undefined; + + // Doing canUser( 'read', 'global_styles' ) returns false even for users with the capability. + // See: https://github.com/WordPress/gutenberg/issues/63438 + // So we need to check the user capabilities directly. + const userId = getCurrentUser()?.id; + const canEditThemeOptions = + userId && getUser( userId )?.capabilities?.edit_theme_options; + + const record = + _globalStylesId && canEditThemeOptions + ? getEditedEntityRecord( + 'root', + 'globalStyles', + _globalStylesId + ) + : undefined; let hasResolved = false; if ( @@ -126,9 +139,23 @@ function useGlobalStylesUserConfig() { function useGlobalStylesBaseConfig() { const baseConfig = useSelect( ( select ) => { - return select( - coreStore - ).__experimentalGetCurrentThemeBaseGlobalStyles(); + const { + getCurrentUser, + getUser, + __experimentalGetCurrentThemeBaseGlobalStyles, + } = select( coreStore ); + + // Doing canUser( 'read', 'global_styles' ) returns false even for users with the capability. + // See: https://github.com/WordPress/gutenberg/issues/63438 + // So we need to check the user capabilities directly. + const userId = getCurrentUser()?.id; + const canEditThemeOptions = + userId && getUser( userId )?.capabilities?.edit_theme_options; + + return ( + canEditThemeOptions && + __experimentalGetCurrentThemeBaseGlobalStyles() + ); }, [] ); return [ !! baseConfig, baseConfig ]; diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index 5aebfb650bfdbc..0d06ff0dca106b 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -36,8 +36,14 @@ export default function PostCardPanel( { actions } ) { getCurrentPostId, __experimentalGetTemplateInfo, } = select( editorStore ); + const { canUser } = select( coreStore ); const { getEditedEntityRecord } = select( coreStore ); - const siteSettings = getEditedEntityRecord( 'root', 'site' ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getEditedEntityRecord( 'root', 'site' ) + : undefined; const _type = getCurrentPostType(); const _id = getCurrentPostId(); const _record = getEditedEntityRecord( 'postType', _type, _id ); diff --git a/packages/editor/src/components/post-content-information/index.js b/packages/editor/src/components/post-content-information/index.js index 7597a6b4697dca..569339ef40c8b9 100644 --- a/packages/editor/src/components/post-content-information/index.js +++ b/packages/editor/src/components/post-content-information/index.js @@ -25,8 +25,14 @@ export default function PostContentInformation() { const { postContent } = useSelect( ( select ) => { const { getEditedPostAttribute, getCurrentPostType, getCurrentPostId } = select( editorStore ); + const { canUser } = select( coreStore ); const { getEntityRecord } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getEntityRecord( 'root', 'site' ) + : undefined; const postType = getCurrentPostType(); const _id = getCurrentPostId(); const isPostsPage = +_id === siteSettings?.page_for_posts; diff --git a/packages/editor/src/components/post-template/hooks.js b/packages/editor/src/components/post-template/hooks.js index 1529228fe95151..c9668cd1443335 100644 --- a/packages/editor/src/components/post-template/hooks.js +++ b/packages/editor/src/components/post-template/hooks.js @@ -23,8 +23,14 @@ export function useAllowSwitchingTemplates() { const { postType, postId } = useEditedPostContext(); return useSelect( ( select ) => { - const { getEntityRecord, getEntityRecords } = select( coreStore ); - const siteSettings = getEntityRecord( 'root', 'site' ); + const { canUser, getEntityRecord, getEntityRecords } = + select( coreStore ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getEntityRecord( 'root', 'site' ) + : undefined; const templates = getEntityRecords( 'postType', 'wp_template', { per_page: -1, } ); diff --git a/packages/editor/src/components/post-url/panel.js b/packages/editor/src/components/post-url/panel.js index 64ba1357221da8..be32b40eaf1046 100644 --- a/packages/editor/src/components/post-url/panel.js +++ b/packages/editor/src/components/post-url/panel.js @@ -61,8 +61,13 @@ export default function PostURLPanel() { function PostURLToggle( { isOpen, onClick } ) { const { slug, isFrontPage, postLink } = useSelect( ( select ) => { const { getCurrentPostId, getCurrentPost } = select( editorStore ); - const { getEditedEntityRecord } = select( coreStore ); - const siteSettings = getEditedEntityRecord( 'root', 'site' ); + const { getEditedEntityRecord, canUser } = select( coreStore ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getEditedEntityRecord( 'root', 'site' ) + : undefined; const _id = getCurrentPostId(); return { slug: select( editorStore ).getEditedPostSlug(), diff --git a/packages/editor/src/components/posts-per-page/index.js b/packages/editor/src/components/posts-per-page/index.js index d62d250d9f3d3d..876644168a52c7 100644 --- a/packages/editor/src/components/posts-per-page/index.js +++ b/packages/editor/src/components/posts-per-page/index.js @@ -24,8 +24,13 @@ export default function PostsPerPage() { const { postsPerPage, isTemplate, postSlug } = useSelect( ( select ) => { const { getEditedPostAttribute, getCurrentPostType } = select( editorStore ); - const { getEditedEntityRecord } = select( coreStore ); - const siteSettings = getEditedEntityRecord( 'root', 'site' ); + const { getEditedEntityRecord, canUser } = select( coreStore ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getEditedEntityRecord( 'root', 'site' ) + : undefined; return { isTemplate: getCurrentPostType() === TEMPLATE_POST_TYPE, postSlug: getEditedPostAttribute( 'slug' ), diff --git a/packages/editor/src/components/site-discussion/index.js b/packages/editor/src/components/site-discussion/index.js index e4bd60db3f8a7c..b80b44b1f59c13 100644 --- a/packages/editor/src/components/site-discussion/index.js +++ b/packages/editor/src/components/site-discussion/index.js @@ -55,8 +55,13 @@ export default function SiteDiscussion() { ( select ) => { const { getEditedPostAttribute, getCurrentPostType } = select( editorStore ); - const { getEditedEntityRecord } = select( coreStore ); - const siteSettings = getEditedEntityRecord( 'root', 'site' ); + const { getEditedEntityRecord, canUser } = select( coreStore ); + const siteSettings = canUser( 'read', { + kind: 'root', + name: 'site', + } ) + ? getEditedEntityRecord( 'root', 'site' ) + : undefined; return { isTemplate: getCurrentPostType() === TEMPLATE_POST_TYPE, postSlug: getEditedPostAttribute( 'slug' ),