mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-16 19:18:30 +02:00
cache IAM policy engines
This commit is contained in:
1 parent
4eb45ecc5e
commit
fcd5bcadcf
2 files changed
+206
-9
No files matched your search
@@ -387,6 +387,136 @@ func TestVerifyActionPermissionPolicyFallback(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestVerifyActionPermissionPolicyFallbackCachesParsedPolicies(t *testing.T) {
|
||||
buildRequest := func(t *testing.T, method string) *http.Request {
|
||||
t.Helper()
|
||||
req, err := http.NewRequest(method, "http://s3.amazonaws.com/test-bucket/test-object", nil)
|
||||
assert.NoError(t, err)
|
||||
return req
|
||||
}
|
||||
|
||||
iam := &IdentityAccessManagement{}
|
||||
content := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::test-bucket/*"}]}`
|
||||
assert.NoError(t, iam.PutPolicy("allowGet", content))
|
||||
|
||||
identity := &Identity{
|
||||
Name: "policy-user",
|
||||
Account: &AccountAdmin,
|
||||
PolicyNames: []string{"allowGet"},
|
||||
}
|
||||
|
||||
errCode := iam.VerifyActionPermission(buildRequest(t, http.MethodGet), identity, Action(ACTION_READ), "test-bucket", "test-object")
|
||||
assert.Equal(t, s3err.ErrNone, errCode)
|
||||
|
||||
cacheKey := newIAMPolicyCacheKey("allowGet", content)
|
||||
iam.policyCacheMu.RLock()
|
||||
firstEngine := iam.iamPolicyCache[cacheKey]
|
||||
firstCacheSize := len(iam.iamPolicyCache)
|
||||
iam.policyCacheMu.RUnlock()
|
||||
|
||||
assert.NotNil(t, firstEngine)
|
||||
assert.Equal(t, 1, firstCacheSize)
|
||||
|
||||
errCode = iam.VerifyActionPermission(buildRequest(t, http.MethodGet), identity, Action(ACTION_READ), "test-bucket", "test-object")
|
||||
assert.Equal(t, s3err.ErrNone, errCode)
|
||||
|
||||
iam.policyCacheMu.RLock()
|
||||
secondEngine := iam.iamPolicyCache[cacheKey]
|
||||
secondCacheSize := len(iam.iamPolicyCache)
|
||||
iam.policyCacheMu.RUnlock()
|
||||
|
||||
assert.Same(t, firstEngine, secondEngine)
|
||||
assert.Equal(t, 1, secondCacheSize)
|
||||
}
|
||||
|
||||
func TestPutPolicyInvalidatesCachedPolicyEngine(t *testing.T) {
|
||||
buildRequest := func(t *testing.T, method string) *http.Request {
|
||||
t.Helper()
|
||||
req, err := http.NewRequest(method, "http://s3.amazonaws.com/test-bucket/test-object", nil)
|
||||
assert.NoError(t, err)
|
||||
return req
|
||||
}
|
||||
|
||||
iam := &IdentityAccessManagement{}
|
||||
initialContent := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::test-bucket/*"}]}`
|
||||
assert.NoError(t, iam.PutPolicy("allowGet", initialContent))
|
||||
|
||||
identity := &Identity{
|
||||
Name: "policy-user",
|
||||
Account: &AccountAdmin,
|
||||
PolicyNames: []string{"allowGet"},
|
||||
}
|
||||
|
||||
errCode := iam.VerifyActionPermission(buildRequest(t, http.MethodGet), identity, Action(ACTION_READ), "test-bucket", "test-object")
|
||||
assert.Equal(t, s3err.ErrNone, errCode)
|
||||
|
||||
initialCacheKey := newIAMPolicyCacheKey("allowGet", initialContent)
|
||||
iam.policyCacheMu.RLock()
|
||||
initialEngine := iam.iamPolicyCache[initialCacheKey]
|
||||
initialCacheSize := len(iam.iamPolicyCache)
|
||||
iam.policyCacheMu.RUnlock()
|
||||
|
||||
assert.NotNil(t, initialEngine)
|
||||
assert.Equal(t, 1, initialCacheSize)
|
||||
|
||||
updatedContent := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::other-bucket/*"}]}`
|
||||
assert.NoError(t, iam.PutPolicy("allowGet", updatedContent))
|
||||
|
||||
iam.policyCacheMu.RLock()
|
||||
_, oldEntryStillCached := iam.iamPolicyCache[initialCacheKey]
|
||||
cacheSizeAfterUpdate := len(iam.iamPolicyCache)
|
||||
iam.policyCacheMu.RUnlock()
|
||||
|
||||
assert.False(t, oldEntryStillCached)
|
||||
assert.Equal(t, 0, cacheSizeAfterUpdate)
|
||||
|
||||
errCode = iam.VerifyActionPermission(buildRequest(t, http.MethodGet), identity, Action(ACTION_READ), "test-bucket", "test-object")
|
||||
assert.Equal(t, s3err.ErrAccessDenied, errCode)
|
||||
|
||||
updatedCacheKey := newIAMPolicyCacheKey("allowGet", updatedContent)
|
||||
iam.policyCacheMu.RLock()
|
||||
updatedEngine := iam.iamPolicyCache[updatedCacheKey]
|
||||
updatedCacheSize := len(iam.iamPolicyCache)
|
||||
iam.policyCacheMu.RUnlock()
|
||||
|
||||
assert.NotNil(t, updatedEngine)
|
||||
assert.NotSame(t, initialEngine, updatedEngine)
|
||||
assert.Equal(t, 1, updatedCacheSize)
|
||||
}
|
||||
|
||||
func TestReplaceS3ApiConfigurationClearsCachedPolicyEngines(t *testing.T) {
|
||||
t.Setenv("AWS_ACCESS_KEY_ID", "")
|
||||
t.Setenv("AWS_SECRET_ACCESS_KEY", "")
|
||||
|
||||
iam := &IdentityAccessManagement{}
|
||||
content := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::test-bucket/*"}]}`
|
||||
_, err := iam.getOrCreateIAMPolicyEngine("allowGet", content)
|
||||
assert.NoError(t, err)
|
||||
|
||||
cacheKey := newIAMPolicyCacheKey("allowGet", content)
|
||||
iam.policyCacheMu.RLock()
|
||||
_, existsBeforeReload := iam.iamPolicyCache[cacheKey]
|
||||
iam.policyCacheMu.RUnlock()
|
||||
assert.True(t, existsBeforeReload)
|
||||
|
||||
config := &iam_pb.S3ApiConfiguration{
|
||||
Policies: []*iam_pb.Policy{
|
||||
{
|
||||
Name: "replacement",
|
||||
Content: `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:ListBucket","Resource":"arn:aws:s3:::test-bucket"}]}`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.NoError(t, iam.ReplaceS3ApiConfiguration(config))
|
||||
|
||||
iam.policyCacheMu.RLock()
|
||||
cacheSizeAfterReload := len(iam.iamPolicyCache)
|
||||
iam.policyCacheMu.RUnlock()
|
||||
|
||||
assert.Equal(t, 0, cacheSizeAfterReload)
|
||||
}
|
||||
|
||||
type LoadS3ApiConfigurationTestCase struct {
|
||||
pbAccount *iam_pb.Account
|
||||
pbIdent *iam_pb.Identity
|
||||
|
||||
Reference in new issue
Block a user