Added missing permissions validation to rewind button (#3282)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
2
.github/workflows/vulncheck.yaml
vendored
2
.github/workflows/vulncheck.yaml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.21.8
|
||||
go-version: 1.21.9
|
||||
check-latest: true
|
||||
- name: Get official govulncheck
|
||||
run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
|
||||
2
go.mod
2
go.mod
@@ -33,7 +33,7 @@ require (
|
||||
github.com/tidwall/gjson v1.17.1
|
||||
github.com/unrolled/secure v1.14.0
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/net v0.23.0
|
||||
golang.org/x/oauth2 v0.18.0
|
||||
// Added to include security fix for
|
||||
// https://github.com/golang/go/issues/56152
|
||||
|
||||
4
go.sum
4
go.sum
@@ -352,8 +352,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
||||
@@ -26,6 +26,7 @@ import get from "lodash/get";
|
||||
import {
|
||||
AccessRuleIcon,
|
||||
ActionsList,
|
||||
Badge,
|
||||
Box,
|
||||
BucketsIcon,
|
||||
Button,
|
||||
@@ -39,7 +40,6 @@ import {
|
||||
RefreshIcon,
|
||||
ScreenTitle,
|
||||
ShareIcon,
|
||||
Badge,
|
||||
} from "mds";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
@@ -274,6 +274,11 @@ const ListObjects = () => {
|
||||
[pathAsResourceInPolicy, ...sessionGrantWildCards],
|
||||
[IAM_SCOPES.S3_GET_OBJECT, IAM_SCOPES.S3_GET_ACTIONS],
|
||||
);
|
||||
const canRewind = hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_GET_OBJECT,
|
||||
IAM_SCOPES.S3_GET_ACTIONS,
|
||||
IAM_SCOPES.S3_GET_BUCKET_VERSIONING,
|
||||
]);
|
||||
const canDelete = hasPermission(
|
||||
[pathAsResourceInPolicy, ...sessionGrantWildCards],
|
||||
[IAM_SCOPES.S3_DELETE_OBJECT],
|
||||
@@ -1057,7 +1062,20 @@ const ListObjects = () => {
|
||||
actions={
|
||||
<Fragment>
|
||||
{!anonymousMode && (
|
||||
<TooltipWrapper tooltip={"Rewind Bucket"}>
|
||||
<TooltipWrapper
|
||||
tooltip={
|
||||
canRewind
|
||||
? "Rewind Bucket"
|
||||
: permissionTooltipHelper(
|
||||
[
|
||||
IAM_SCOPES.S3_GET_OBJECT,
|
||||
IAM_SCOPES.S3_GET_ACTIONS,
|
||||
IAM_SCOPES.S3_GET_BUCKET_VERSIONING,
|
||||
],
|
||||
"apply rewind in this bucket",
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
id={"rewind-objects-list"}
|
||||
label={"Rewind"}
|
||||
@@ -1078,13 +1096,7 @@ const ListObjects = () => {
|
||||
onClick={() => {
|
||||
setRewindSelect(true);
|
||||
}}
|
||||
disabled={
|
||||
!isVersioningApplied ||
|
||||
!hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_GET_OBJECT,
|
||||
IAM_SCOPES.S3_GET_ACTIONS,
|
||||
])
|
||||
}
|
||||
disabled={!isVersioningApplied || !canRewind}
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
)}
|
||||
|
||||
@@ -17,10 +17,20 @@
|
||||
import * as roles from "../utils/roles";
|
||||
import * as elements from "../utils/elements";
|
||||
import * as functions from "../utils/functions";
|
||||
import { testBucketBrowseButtonFor } from "../utils/functions";
|
||||
import {
|
||||
namedTestBucketBrowseButtonFor,
|
||||
setUpNamedBucket,
|
||||
setVersionedBucket,
|
||||
testBucketBrowseButtonFor,
|
||||
} from "../utils/functions";
|
||||
import { Selector } from "testcafe";
|
||||
import { deniedError, file } from "../permissions-6/resourceTesting";
|
||||
|
||||
fixture("Rewind Testing").page("http://localhost:9090");
|
||||
|
||||
const bucketname = "bucketname";
|
||||
const test3BucketBrowseButton = namedTestBucketBrowseButtonFor(bucketname);
|
||||
|
||||
test
|
||||
.before(async (t) => {
|
||||
// Create a bucket
|
||||
@@ -57,3 +67,80 @@ test
|
||||
// Cleanup created bucket and corresponding uploads
|
||||
await functions.cleanUpBucketAndUploads(t, "abucketrewind");
|
||||
});
|
||||
|
||||
test
|
||||
.before(async (t) => {
|
||||
await functions.setUpNamedBucket(t, bucketname);
|
||||
await functions.setVersionedBucket(t, bucketname);
|
||||
await functions.uploadNamedObjectToBucket(
|
||||
t,
|
||||
bucketname,
|
||||
"test.txt",
|
||||
"web-app/tests/uploads/test.txt",
|
||||
);
|
||||
await functions.uploadNamedObjectToBucket(
|
||||
t,
|
||||
bucketname,
|
||||
"firstlevel/secondlevel/test.txt",
|
||||
"web-app/tests/uploads/test.txt",
|
||||
);
|
||||
})("Rewind button enabled in bucket", async (t) => {
|
||||
await t
|
||||
.useRole(roles.rewindEnabled)
|
||||
.navigateTo(`http://localhost:9090/browser`)
|
||||
.click(test3BucketBrowseButton)
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel"),
|
||||
)
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("secondlevel"),
|
||||
)
|
||||
.wait(1500)
|
||||
.expect(elements.rewindButton.exists)
|
||||
.ok();
|
||||
})
|
||||
.after(async (t) => {
|
||||
await functions.cleanUpNamedBucketAndUploads(t, bucketname);
|
||||
});
|
||||
|
||||
test
|
||||
.before(async (t) => {
|
||||
await functions.setUpNamedBucket(t, bucketname);
|
||||
await functions.setVersionedBucket(t, bucketname);
|
||||
await functions.uploadNamedObjectToBucket(
|
||||
t,
|
||||
bucketname,
|
||||
"test.txt",
|
||||
"web-app/tests/uploads/test.txt",
|
||||
);
|
||||
await functions.uploadNamedObjectToBucket(
|
||||
t,
|
||||
bucketname,
|
||||
"firstlevel/secondlevel/test.txt",
|
||||
"web-app/tests/uploads/test.txt",
|
||||
);
|
||||
})("Rewind button disabled in bucket", async (t) => {
|
||||
await t
|
||||
.useRole(roles.rewindNotEnabled)
|
||||
.navigateTo(`http://localhost:9090/browser`)
|
||||
.click(test3BucketBrowseButton)
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel"),
|
||||
)
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("secondlevel"),
|
||||
)
|
||||
.wait(1500)
|
||||
.expect(elements.rewindButton.exists)
|
||||
.ok()
|
||||
.wait(1500)
|
||||
.expect(elements.rewindButton.hasAttribute("disabled"))
|
||||
.ok();
|
||||
})
|
||||
.after(async (t) => {
|
||||
await functions.cleanUpNamedBucketAndUploads(t, bucketname);
|
||||
});
|
||||
|
||||
36
web-app/tests/policies/rewind-allowed.json
Normal file
36
web-app/tests/policies/rewind-allowed.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Deny",
|
||||
"Action": ["s3:CreateBucket", "s3:DeleteBucket"],
|
||||
"Resource": ["arn:aws:s3:::*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:ListBucket"],
|
||||
"Resource": ["arn:aws:s3:::bucketname"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:GetBucketLocation", "s3:GetBucketVersioning"],
|
||||
"Resource": ["arn:aws:s3:::bucketname"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:GetObject"],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::bucketname/firstlevel",
|
||||
"arn:aws:s3:::bucketname/firstlevel/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:*"],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::bucketname/firstlevel/secondlevel*",
|
||||
"arn:aws:s3:::bucketname/firstlevel/secondlevel/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
36
web-app/tests/policies/rewind-not-allowed.json
Normal file
36
web-app/tests/policies/rewind-not-allowed.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Deny",
|
||||
"Action": ["s3:CreateBucket", "s3:DeleteBucket"],
|
||||
"Resource": ["arn:aws:s3:::*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:ListBucket"],
|
||||
"Resource": ["arn:aws:s3:::bucketname"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:GetBucketLocation"],
|
||||
"Resource": ["arn:aws:s3:::bucketname"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:GetObject"],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::bucketname/firstlevel",
|
||||
"arn:aws:s3:::bucketname/firstlevel/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:*"],
|
||||
"Resource": [
|
||||
"arn:aws:s3:::bucketname/firstlevel/secondlevel*",
|
||||
"arn:aws:s3:::bucketname/firstlevel/secondlevel/*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -32,6 +32,8 @@ remove_users() {
|
||||
mc admin user remove minio conditions-2-$TIMESTAMP
|
||||
mc admin user remove minio conditions-3-$TIMESTAMP
|
||||
mc admin user remove minio conditions-4-$TIMESTAMP
|
||||
mc admin user remove minio rewind-allowed-$TIMESTAMP
|
||||
mc admin user remove minio rewind-not-allowed-$TIMESTAMP
|
||||
}
|
||||
|
||||
remove_policies() {
|
||||
@@ -58,6 +60,8 @@ remove_policies() {
|
||||
mc admin policy remove minio conditions-policy-2-$TIMESTAMP
|
||||
mc admin policy remove minio conditions-policy-3-$TIMESTAMP
|
||||
mc admin policy remove minio conditions-policy-4-$TIMESTAMP
|
||||
mc admin policy remove minio rewind-allowed-$TIMESTAMP
|
||||
mc admin policy remove minio rewind-not-allowed-$TIMESTAMP
|
||||
}
|
||||
|
||||
__init__() {
|
||||
|
||||
@@ -47,6 +47,8 @@ create_policies() {
|
||||
mc admin policy create minio conditions-policy-2-$TIMESTAMP web-app/tests/policies/conditionsPolicy2.json
|
||||
mc admin policy create minio conditions-policy-3-$TIMESTAMP web-app/tests/policies/conditionsPolicy3.json
|
||||
mc admin policy create minio conditions-policy-4-$TIMESTAMP web-app/tests/policies/conditionsPolicy4.json
|
||||
mc admin policy create minio rewind-allowed-$TIMESTAMP web-app/tests/policies/rewind-allowed.json
|
||||
mc admin policy create minio rewind-not-allowed-$TIMESTAMP web-app/tests/policies/rewind-not-allowed.json
|
||||
}
|
||||
|
||||
create_users() {
|
||||
@@ -78,6 +80,8 @@ create_users() {
|
||||
mc admin user add minio conditions-2-$TIMESTAMP conditions1234
|
||||
mc admin user add minio conditions-3-$TIMESTAMP conditions1234
|
||||
mc admin user add minio conditions-4-$TIMESTAMP conditions1234
|
||||
mc admin user add minio rewind-allowed-$TIMESTAMP rewindallowed1234
|
||||
mc admin user add minio rewind-not-allowed-$TIMESTAMP rewindnotallowed1234
|
||||
}
|
||||
|
||||
create_buckets() {
|
||||
@@ -114,4 +118,6 @@ assign_policies() {
|
||||
mc admin policy attach minio conditions-policy-2-$TIMESTAMP --user conditions-2-$TIMESTAMP
|
||||
mc admin policy attach minio conditions-policy-3-$TIMESTAMP --user conditions-3-$TIMESTAMP
|
||||
mc admin policy attach minio conditions-policy-4-$TIMESTAMP --user conditions-4-$TIMESTAMP
|
||||
mc admin policy attach minio rewind-allowed-$TIMESTAMP --user rewind-allowed-$TIMESTAMP
|
||||
mc admin policy attach minio rewind-not-allowed-$TIMESTAMP --user rewind-not-allowed-$TIMESTAMP
|
||||
}
|
||||
|
||||
@@ -294,3 +294,25 @@ export const conditions4 = Role(
|
||||
},
|
||||
{ preserveUrl: true },
|
||||
);
|
||||
|
||||
export const rewindEnabled = Role(
|
||||
loginUrl,
|
||||
async (t) => {
|
||||
await t
|
||||
.typeText("#accessKey", "rewind-allowed-" + unixTimestamp)
|
||||
.typeText("#secretKey", "rewindallowed1234")
|
||||
.click(submitButton);
|
||||
},
|
||||
{ preserveUrl: true },
|
||||
);
|
||||
|
||||
export const rewindNotEnabled = Role(
|
||||
loginUrl,
|
||||
async (t) => {
|
||||
await t
|
||||
.typeText("#accessKey", "rewind-not-allowed-" + unixTimestamp)
|
||||
.typeText("#secretKey", "rewindnotallowed1234")
|
||||
.click(submitButton);
|
||||
},
|
||||
{ preserveUrl: true },
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user