mirror of
https://github.com/penpot/penpot.git
synced 2026-08-19 03:08:40 +00:00
🐛 Add user:read permission checks to plugin API
Add permission checks to user identity accessors that were bypassing the consent model, allowing plugins to access user data regardless of whether the user granted user:read permission. Changes: - api.cljs: Add user:read checks to getCurrentUser and getActiveUsers - comments.cljs: Add user:read checks to comment-proxy and comment-thread-proxy owner/user getters - file.cljs: Add user:read check to file-version-proxy createdBy getter When user:read permission is not granted: - getCurrentUser() returns null - getActiveUsers() returns empty array - owner/user/createdBy getters return null Follows the established pattern from other permission checks in the plugin API. Relates to #11137 AI-assisted-by: qwen3.7-plus
This commit is contained in:
parent
796a76ff32
commit
73e35555ab
@ -47,6 +47,7 @@
|
||||
[app.plugins.local-storage :as local-storage]
|
||||
[app.plugins.page :as page]
|
||||
[app.plugins.parser :as parser]
|
||||
[app.plugins.register :as r]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.system-events :as se]
|
||||
[app.plugins.user :as user]
|
||||
@ -242,15 +243,18 @@
|
||||
|
||||
:getCurrentUser
|
||||
(fn []
|
||||
(user/current-user-proxy plugin-id (:session-id @st/state)))
|
||||
(when (r/check-permission plugin-id "user:read")
|
||||
(user/current-user-proxy plugin-id (:session-id @st/state))))
|
||||
|
||||
:getActiveUsers
|
||||
(fn []
|
||||
(apply array
|
||||
(->> (:workspace-presence @st/state)
|
||||
(vals)
|
||||
(remove #(= (:id %) (:session-id @st/state)))
|
||||
(map #(user/active-user-proxy plugin-id (:id %))))))
|
||||
(if (r/check-permission plugin-id "user:read")
|
||||
(apply array
|
||||
(->> (:workspace-presence @st/state)
|
||||
(vals)
|
||||
(remove #(= (:id %) (:session-id @st/state)))
|
||||
(map #(user/active-user-proxy plugin-id (:id %)))))
|
||||
(array)))
|
||||
|
||||
:uploadMediaUrl
|
||||
(fn [name url]
|
||||
|
||||
@ -40,12 +40,14 @@
|
||||
|
||||
;; FIXME: inconsistent with comment-thread: owner
|
||||
:user
|
||||
{:get #(->> (dc/get-owner data)
|
||||
(user/user-proxy plugin-id))}
|
||||
{:get #(when (r/check-permission plugin-id "user:read")
|
||||
(->> (dc/get-owner data)
|
||||
(user/user-proxy plugin-id)))}
|
||||
|
||||
:owner
|
||||
{:get #(->> (dc/get-owner data)
|
||||
(user/user-proxy plugin-id))}
|
||||
{:get #(when (r/check-permission plugin-id "user:read")
|
||||
(->> (dc/get-owner data)
|
||||
(user/user-proxy plugin-id)))}
|
||||
|
||||
:date
|
||||
{:get
|
||||
@ -116,8 +118,9 @@
|
||||
:board {:get #(shape/shape-proxy plugin-id file-id page-id (:frame-id data))}
|
||||
|
||||
:owner
|
||||
{:get #(->> (dc/get-owner data)
|
||||
(user/user-proxy plugin-id))}
|
||||
{:get #(when (r/check-permission plugin-id "user:read")
|
||||
(->> (dc/get-owner data)
|
||||
(user/user-proxy plugin-id)))}
|
||||
|
||||
:position
|
||||
{:get
|
||||
|
||||
@ -61,8 +61,9 @@
|
||||
:createdBy
|
||||
{:get
|
||||
(fn []
|
||||
(when-let [user-data (get users (:profile-id @data))]
|
||||
(user/user-proxy plugin-id user-data)))}
|
||||
(when (r/check-permission plugin-id "user:read")
|
||||
(when-let [user-data (get users (:profile-id @data))]
|
||||
(user/user-proxy plugin-id user-data))))}
|
||||
|
||||
:createdAt
|
||||
{:get #(:created-at @data)}
|
||||
|
||||
80
frontend/test/frontend_tests/plugins/user_test.cljs
Normal file
80
frontend/test/frontend_tests/plugins/user_test.cljs
Normal file
@ -0,0 +1,80 @@
|
||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC Sucursal en España SL
|
||||
|
||||
(ns frontend-tests.plugins.user-test
|
||||
(:require
|
||||
[app.main.data.comments :as dc]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.api :as api]
|
||||
[app.plugins.comments :as comments]
|
||||
[app.plugins.file :as file]
|
||||
[app.plugins.register :as r]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[frontend-tests.helpers.mock :as mock]))
|
||||
|
||||
(def ^:private plugin-id "00000000-0000-0000-0000-000000000000")
|
||||
|
||||
(t/deftest comment-thread-owner-returns-nil-without-user-read
|
||||
(let [owner-id (random-uuid)
|
||||
file-id (random-uuid)
|
||||
page-id (random-uuid)
|
||||
thread-id (random-uuid)
|
||||
thread (comments/comment-thread-proxy
|
||||
plugin-id
|
||||
file-id
|
||||
page-id
|
||||
{:id thread-id :owner-id owner-id})]
|
||||
(with-redefs [r/check-permission (constantly false)
|
||||
dc/get-owner (constantly {:id owner-id :fullname "Owner"})]
|
||||
(t/is (nil? (.-owner thread)))
|
||||
(t/is (nil? (.-user thread))))))
|
||||
|
||||
(t/deftest comment-reply-owner-returns-nil-without-user-read
|
||||
(let [owner-id (random-uuid)
|
||||
file-id (random-uuid)
|
||||
page-id (random-uuid)
|
||||
thread-id (random-uuid)
|
||||
reply-id (random-uuid)
|
||||
reply (comments/comment-proxy
|
||||
plugin-id
|
||||
file-id
|
||||
page-id
|
||||
thread-id
|
||||
{:id reply-id :owner-id owner-id})]
|
||||
(with-redefs [r/check-permission (constantly false)
|
||||
dc/get-owner (constantly {:id owner-id :fullname "Owner"})]
|
||||
(t/is (nil? (.-owner reply)))
|
||||
(t/is (nil? (.-user reply))))))
|
||||
|
||||
(t/deftest file-version-created-by-returns-nil-without-user-read
|
||||
(let [file-id (random-uuid)
|
||||
version-id (random-uuid)
|
||||
profile-id (random-uuid)
|
||||
version (file/file-version-proxy
|
||||
plugin-id
|
||||
file-id
|
||||
{profile-id {:id profile-id :fullname "User"}}
|
||||
{:id version-id
|
||||
:label "Version"
|
||||
:created-at (js/Date.)
|
||||
:profile-id profile-id})]
|
||||
(with-redefs [r/check-permission (constantly false)]
|
||||
(t/is (nil? (.-createdBy version))))))
|
||||
|
||||
(t/deftest get-current-user-returns-nil-without-user-read
|
||||
(let [ctx (api/create-context plugin-id)]
|
||||
(with-redefs [r/check-permission (constantly false)
|
||||
st/state (atom {:session-id (random-uuid)
|
||||
:profile {:id (random-uuid) :fullname "User"}})]
|
||||
(t/is (nil? (.getCurrentUser ctx))))))
|
||||
|
||||
(t/deftest get-active-users-returns-empty-without-user-read
|
||||
(let [ctx (api/create-context plugin-id)]
|
||||
(with-redefs [r/check-permission (constantly false)
|
||||
st/state (atom {:session-id (random-uuid)
|
||||
:profile {:id (random-uuid)}
|
||||
:workspace-presence {(random-uuid) {:id (random-uuid)}}})]
|
||||
(t/is (zero? (.-length (.getActiveUsers ctx)))))))
|
||||
@ -53,6 +53,7 @@
|
||||
[frontend-tests.plugins.shape-bugfixes-test]
|
||||
[frontend-tests.plugins.text-test]
|
||||
[frontend-tests.plugins.tokens-test]
|
||||
[frontend-tests.plugins.user-test]
|
||||
[frontend-tests.plugins.utils-test]
|
||||
[frontend-tests.plugins.value-objects-test]
|
||||
[frontend-tests.render-dimensions-test]
|
||||
@ -150,6 +151,7 @@
|
||||
'frontend-tests.plugins.shape-bugfixes-test
|
||||
'frontend-tests.plugins.text-test
|
||||
'frontend-tests.plugins.tokens-test
|
||||
'frontend-tests.plugins.user-test
|
||||
'frontend-tests.plugins.utils-test
|
||||
'frontend-tests.plugins.value-objects-test
|
||||
'frontend-tests.render-wasm.process-objects-test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user