Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Metabase
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Engineering Digital Service
Metabase
Commits
8fc98927
Unverified
Commit
8fc98927
authored
4 months ago
by
Noah Moss
Committed by
GitHub
4 months ago
Browse files
Options
Downloads
Patches
Plain Diff
Clarify cache API permissions and add tests (#49804)
parent
a9819e8c
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
enterprise/backend/test/metabase_enterprise/cache/cache_test.clj
+56
-10
56 additions, 10 deletions
...ise/backend/test/metabase_enterprise/cache/cache_test.clj
src/metabase/api/cache.clj
+10
-9
10 additions, 9 deletions
src/metabase/api/cache.clj
with
66 additions
and
19 deletions
enterprise/backend/test/metabase_enterprise/cache/cache_test.clj
+
56
−
10
View file @
8fc98927
...
@@ -27,16 +27,6 @@
...
@@ -27,16 +27,6 @@
:database_id
(
:id
db
)
:database_id
(
:id
db
)
:collection_id
(
:id
col1
)}
:collection_id
(
:id
col1
)}
:model/Card
card3
{
:name
"card3"
}]
:model/Card
card3
{
:name
"card3"
}]
(
testing
"Access from regular users"
(
testing
"No general access"
(
is
(
=
"You don't have permissions to do that."
(
mt/user-http-request
:rasta
:get
403
"cache/"
))))
(
testing
"But have access to a separate (accessible to them) entities"
(
is
(
=
{
:data
[]}
(
mt/user-http-request
:rasta
:get
200
"cache/"
:model
"question"
:id
(
:id
card1
))))))
(
testing
"Can configure root"
(
testing
"Can configure root"
(
is
(
mt/user-http-request
:crowberto
:put
200
"cache/"
(
is
(
mt/user-http-request
:crowberto
:put
200
"cache/"
{
:model
"root"
{
:model
"root"
...
@@ -118,6 +108,62 @@
...
@@ -118,6 +108,62 @@
:strategy
{
:type
"schedule"
:strategy
{
:type
"schedule"
:schedule
"0/2 * * * * ?"
}}))))))))
:schedule
"0/2 * * * * ?"
}}))))))))
(
deftest
cache-config-permissions-test
(
mt/with-model-cleanup
[
:model/CacheConfig
]
(
mt/with-premium-features
#
{
:cache-granular-controls
:audit-app
}
(
mt/with-temp
[
:model/Database
{
db-id
:id
}
{}
:model/Collection
{
collection-id
:id
}
{
:name
"col1"
}
:model/Dashboard
{
dashboard-id
:id
}
{
:name
"dash1"
:collection_id
collection-id
}
:model/Card
{
card-id
:id
}
{
:name
"card1"
:database_id
db-id
:collection_id
collection-id
}]
(
testing
"Non-admins have no general access to cache config"
(
is
(
=
"You don't have permissions to do that."
(
mt/user-http-request
:rasta
:get
403
"cache/"
))))
(
testing
"Non-admins can access cache config only if they have write access to the model"
(
mt/with-all-users-data-perms-graph!
{
db-id
{
:details
:yes
}}
(
doseq
[[
model
id
]
[[
"question"
card-id
]
[
"database"
db-id
]
[
"dashboard"
dashboard-id
]]]
(
testing
(
format
"\nTesting cache config for %s %d"
model
id
)
(
is
(
=
{
:data
[]}
(
mt/user-http-request
:rasta
:get
200
"cache/"
:model
model
:id
id
)))
(
is
(
mt/user-http-request
:rasta
:put
200
"cache/"
{
:model
model
:model_id
id
:strategy
{
:type
"nocache"
:name
"card1"
}}))
(
is
(
=?
{
:count
1
}
(
mt/user-http-request
:rasta
:post
200
"cache/invalidate"
(
keyword
model
)
[
id
])))
(
is
(
nil?
(
mt/user-http-request
:rasta
:delete
204
"cache/"
{
:model
model
:model_id
id
})))))))
(
testing
"Non-admins cannot access cache config if they do not have write access to the model"
(
mt/with-all-users-data-perms-graph!
{
db-id
{
:details
:no
}}
(
mt/with-non-admin-groups-no-collection-perms
collection-id
(
doseq
[[
model
id
]
[[
"question"
card-id
]
[
"database"
db-id
]
[
"dashboard"
dashboard-id
]]]
(
testing
(
format
"\nTesting cache config for %s %d"
model
id
)
(
mt/user-http-request
:rasta
:get
403
"cache/"
:model
model
:id
id
)
(
mt/user-http-request
:rasta
:put
403
"cache/"
{
:model
model
:model_id
id
:strategy
{
:type
"nocache"
:name
"card1"
}})
(
mt/user-http-request
:rasta
:post
403
"cache/invalidate"
(
keyword
model
)
[
id
])
(
mt/user-http-request
:rasta
:delete
403
"cache/"
{
:model
model
:model_id
id
}))))))))))
(
deftest
invalidation-test
(
deftest
invalidation-test
(
mt/with-model-cleanup
[
:model/CacheConfig
(
mt/with-model-cleanup
[
:model/CacheConfig
[
:model/QueryCache
:updated_at
]]
[
:model/QueryCache
:updated_at
]]
...
...
This diff is collapsed.
Click to expand it.
src/metabase/api/cache.clj
+
10
−
9
View file @
8fc98927
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
[
clojure.walk
:as
walk
]
[
clojure.walk
:as
walk
]
[
compojure.core
:refer
[
GET
]]
[
compojure.core
:refer
[
GET
]]
[
metabase.api.common
:as
api
]
[
metabase.api.common
:as
api
]
[
metabase.api.common.validation
:as
validation
]
[
metabase.models.cache-config
:as
cache-config
]
[
metabase.models.cache-config
:as
cache-config
]
[
metabase.public-settings.premium-features
:as
premium-features
:refer
[
defenterprise
]]
[
metabase.public-settings.premium-features
:as
premium-features
:refer
[
defenterprise
]]
[
metabase.util.i18n
:refer
[
tru
trun
]]
[
metabase.util.i18n
:refer
[
tru
trun
]]
...
@@ -67,8 +66,8 @@
...
@@ -67,8 +66,8 @@
;; sometimes its a sequence and we're going to check for settings access anyway
;; sometimes its a sequence and we're going to check for settings access anyway
(
not
(
number?
id
))
(
not
(
number?
id
))
(
zero?
id
))
(
zero?
id
))
;; if you're not accessing a concrete entity, you
should be able to access settings
;; if you're not accessing a concrete entity, you
have to be an admin
(
validation/check-has-application-permission
:setting
)
(
api/check-superuser
)
(
api/write-check
(
case
model
(
api/write-check
(
case
model
"database"
:model/Database
"database"
:model/Database
"dashboard"
:model/Dashboard
"dashboard"
:model/Dashboard
...
@@ -98,7 +97,6 @@
...
@@ -98,7 +97,6 @@
{
model
cache-config/CachingModel
{
model
cache-config/CachingModel
model_id
ms/IntGreaterThanOrEqualToZero
model_id
ms/IntGreaterThanOrEqualToZero
strategy
(
CacheStrategyAPI
)}
strategy
(
CacheStrategyAPI
)}
(
validation/check-has-application-permission
:setting
)
(
assert-valid-models
model
[
model_id
]
(
premium-features/enable-cache-granular-controls?
))
(
assert-valid-models
model
[
model_id
]
(
premium-features/enable-cache-granular-controls?
))
(
check-cache-access
model
model_id
)
(
check-cache-access
model
model_id
)
{
:id
(
cache-config/store!
api/*current-user-id*
config
)})
{
:id
(
cache-config/store!
api/*current-user-id*
config
)})
...
@@ -108,9 +106,8 @@
...
@@ -108,9 +106,8 @@
[
:as
{{
:keys
[
model
model_id
]}
:body
}]
[
:as
{{
:keys
[
model
model_id
]}
:body
}]
{
model
cache-config/CachingModel
{
model
cache-config/CachingModel
model_id
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)}
model_id
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)}
(
validation/check-has-application-permission
:setting
)
(
assert-valid-models
model
model_id
(
premium-features/enable-cache-granular-controls?
))
(
assert-valid-models
model
model_id
(
premium-features/enable-cache-granular-controls?
))
(
check-cache-access
model
model_
id
)
(
doseq
[
id
model_id
]
(
check-cache-access
model
id
)
)
(
cache-config/delete!
api/*current-user-id*
model
model_id
)
(
cache-config/delete!
api/*current-user-id*
model
model_id
)
nil
)
nil
)
...
@@ -124,13 +121,17 @@
...
@@ -124,13 +121,17 @@
touching all nested configurations, or you want your invalidation to trickle down to every card."
touching all nested configurations, or you want your invalidation to trickle down to every card."
[
include
database
dashboard
question
]
[
include
database
dashboard
question
]
{
include
[
:maybe
{
:description
"All cache configuration overrides should invalidate cache too"
}
[
:=
:overrides
]]
{
include
[
:maybe
{
:description
"All cache configuration overrides should invalidate cache too"
}
[
:=
:overrides
]]
database
[
:maybe
{
:description
"A database id"
}
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)]
database
[
:maybe
{
:description
"A
list of
database id
s
"
}
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)]
dashboard
[
:maybe
{
:description
"A dashboard id"
}
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)]
dashboard
[
:maybe
{
:description
"A
list of
dashboard id
s
"
}
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)]
question
[
:maybe
{
:description
"A question id"
}
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)]}
question
[
:maybe
{
:description
"A
list of
question id
s
"
}
(
ms/QueryVectorOf
ms/IntGreaterThanOrEqualToZero
)]}
(
when-not
(
premium-features/enable-cache-granular-controls?
)
(
when-not
(
premium-features/enable-cache-granular-controls?
)
(
throw
(
premium-features/ee-feature-error
(
tru
"Granular Caching"
))))
(
throw
(
premium-features/ee-feature-error
(
tru
"Granular Caching"
))))
(
doseq
[
db-id
database
]
(
api/write-check
:model/Database
db-id
))
(
doseq
[
dashboard-id
dashboard
]
(
api/write-check
:model/Dashboard
dashboard-id
))
(
doseq
[
question-id
question
]
(
api/write-check
:model/Card
question-id
))
(
let
[
cnt
(
cache-config/invalidate!
{
:databases
database
(
let
[
cnt
(
cache-config/invalidate!
{
:databases
database
:dashboards
dashboard
:dashboards
dashboard
:questions
question
:questions
question
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment