Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4070b72
Automate permission testing
kaankabalak Dec 8, 2021
3f1bca4
Update yarn.lock
kaankabalak Jan 12, 2022
6a4e747
Update Copyright date on new files
kaankabalak Jan 12, 2022
45be099
Fix tests that didn't pass after recent UI changes
kaankabalak Jan 13, 2022
940d7ff
Update yarn.lock
kaankabalak Jan 13, 2022
85c4c0b
Use relative path to fix 'PWD not found' Github Actions error
kaankabalak Jan 13, 2022
92f97b8
Add command to install Testcafe
kaankabalak Jan 13, 2022
876b243
Run tests in headless mode as Github Actions can't run with GUI
kaankabalak Jan 13, 2022
a818702
Start frontend app in separate command
kaankabalak Jan 13, 2022
a15591a
Wait until frontend app launches
kaankabalak Jan 13, 2022
a463144
Use Quarantine mode for tests
kaankabalak Jan 13, 2022
76a287d
Revert timestamp
kaankabalak Jan 13, 2022
b0bb577
Fix tests for updated Policy textfield
kaankabalak Jan 14, 2022
62f633f
Use TestCafe Github Action
kaankabalak Jan 14, 2022
6bc203d
Run MinIO on Docker
kaankabalak Jan 14, 2022
f553bc4
Add command to start front-end app
kaankabalak Jan 14, 2022
ee1235b
Run commands asynchronously
kaankabalak Jan 14, 2022
02a26db
Add sleep command
kaankabalak Jan 14, 2022
83189b5
Add additional delay
kaankabalak Jan 14, 2022
c9cb487
Update sleep duration
kaankabalak Jan 14, 2022
57cdcc4
Update sleep duration to 150
kaankabalak Jan 14, 2022
0799a18
Fix tests after recent UI updates
kaankabalak Jan 14, 2022
38d7803
Fix clean up script
kaankabalak Jan 14, 2022
2345fc1
Update sleep duration to 180
kaankabalak Jan 14, 2022
904e9e9
Update package.json spacing
kaankabalak Jan 14, 2022
aad9e74
Comment out test failing sporadically on GitHub Actions
kaankabalak Jan 14, 2022
22c6e00
Comment out randomly failing test
kaankabalak Jan 15, 2022
f52db6b
Merge branch 'master' into permission-testing-final
dvaldivia Jan 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/permissions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: "Front-End Permission Tests"

on:
pull_request:
branches:
- master
push:
branches:
- master

jobs:
permissions:
name: Front-End Permission Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [1.17.x]
os: [ubuntu-latest]
steps:
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v2

- name: Build Console on ${{ matrix.os }}
env:
GO111MODULE: on
GOOS: linux
run: |
make console

- name: Start Console, front-end app and initialize users/policies
run: |
(./console server && sleep 180) & (cd portal-ui && yarn && yarn start && sleep 180) & (make initialize-permissions && sleep 180)

- name: Run TestCafe Tests
uses: DevExpress/testcafe-action@latest
with:
args: '"chrome:headless" portal-ui/tests/permissions/ --skip-js-errors'

- name: Clean up users & policies
run: |
make cleanup-permissions
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ test-integration:
@(GO111MODULE=on go test -race -v github.com/minio/console/integration/...)
@(docker stop minio)

test-permissions:
@(docker run -d --name minio --rm -p 9000:9000 quay.io/minio/minio:latest server /data{1...4})
@(env bash $(PWD)/portal-ui/tests/scripts/permissions.sh)
@(docker stop minio)

initialize-permissions:
@(docker run -d --name minio --rm -p 9000:9000 quay.io/minio/minio:latest server /data{1...4})
@(env bash $(PWD)/portal-ui/tests/scripts/initialize-env.sh)

cleanup-permissions:
@(env bash $(PWD)/portal-ui/tests/scripts/cleanup-env.sh)
@(docker stop minio)

test:
@(GO111MODULE=on go test -race -v github.com/minio/console/restapi/...)

Expand Down
1 change: 1 addition & 0 deletions portal-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"redux-thunk": "^2.3.0",
"styled-components": "^5.3.1",
"superagent": "^6.1.0",
"testcafe": "^1.17.1",
"typeface-roboto": "^0.0.75",
"use-debounce": "^5.0.1",
"websocket": "^1.0.31"
Expand Down
1 change: 1 addition & 0 deletions portal-ui/tests/constants/timestamp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1642030641
62 changes: 62 additions & 0 deletions portal-ui/tests/permissions/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import * as roles from "../utils/roles";
import * as elements from "../utils/elements";

fixture("For user with Admin permissions")
.page("http://localhost:5005")
.beforeEach(async (t) => {
await t.useRole(roles.admin);
});

test("All sidebar items exist", async (t) => {
const dashboardExists = elements.dashboardElement.exists;
const bucketsExist = elements.bucketsElement.exists;
const usersExist = elements.usersElement.exists;
const groupsExist = elements.groupsElement.exists;
const serviceAcctsExist = elements.serviceAcctsElement.exists;
const iamPoliciesExist = elements.iamPoliciesElement.exists;
const settingsExist = elements.settingsElement.exists;
const notificationEndpointsExist =
elements.notificationEndpointsElement.exists;
const tiersExist = elements.tiersElement.exists;
const toolsExist = elements.toolsElement.exists;
const licenseExists = elements.licenseElement.exists;
await t
.expect(dashboardExists)
.ok()
.expect(bucketsExist)
.ok()
.expect(usersExist)
.ok()
.expect(groupsExist)
.ok()
.expect(serviceAcctsExist)
.ok()
.expect(iamPoliciesExist)
.ok()
.expect(settingsExist)
.ok()
.expect(notificationEndpointsExist)
.ok()
.expect(tiersExist)
.ok()
.expect(toolsExist)
.ok()
.expect(licenseExists)
.ok();
});
86 changes: 86 additions & 0 deletions portal-ui/tests/permissions/bucketAssignPolicy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";

fixture("For user with Bucket Assign Policy permissions")
.page("http://localhost:5005")
.beforeEach(async (t) => {
await t.useRole(roles.bucketAssignPolicy);
});

// Bucket assign policy permissions
test("Buckets sidebar item exists", async (t) => {
const bucketsExist = elements.bucketsElement.exists;
await t.expect(bucketsExist).ok();
});

test.before(async (t) => {
// Create a bucket
await functions.setUpBucket(t);
})("A readonly policy can be assigned to a bucket", async (t) => {
await t
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
.useRole(roles.bucketAssignPolicy)
.navigateTo("http://localhost:5005/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.addAccessRuleButton)
.typeText(elements.bucketsPrefixInput, "readonlytest")
.click(elements.bucketsAccessInput)
.click(elements.bucketsAccessReadOnlyInput)
.click(elements.saveButton);
});

test("A writeonly policy can be assigned to a bucket", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.addAccessRuleButton)
.typeText(elements.bucketsPrefixInput, "writeonlytest")
.click(elements.bucketsAccessInput)
.click(elements.bucketsAccessWriteOnlyInput)
.click(elements.saveButton);
});

test("A readwrite policy can be assigned to a bucket", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.addAccessRuleButton)
.typeText(elements.bucketsPrefixInput, "readwritetest")
.click(elements.bucketsAccessInput)
.click(elements.bucketsAccessReadWriteInput)
.click(elements.saveButton);
});

test("Previously assigned policy to a bucket can be deleted", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.manageButton)
.click(elements.bucketAccessRulesTab)
.click(elements.deleteIconButtonAlt)
.click(elements.deleteButton)
.click(elements.logoutItem);
}).after(async (t) => {
// Cleanup created bucket
await functions.cleanUpBucket(t);
});
66 changes: 66 additions & 0 deletions portal-ui/tests/permissions/bucketRead.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";

fixture("For user with Bucket Read permissions")
.page("http://localhost:5005")
.beforeEach(async (t) => {
await t.useRole(roles.bucketRead);
});

test("Buckets sidebar item exists", async (t) => {
const bucketsExist = elements.bucketsElement.exists;
await t.expect(bucketsExist).ok();
});

test.before(async (t) => {
// Create a bucket
await functions.setUpBucket(t);
})("Browse button exists", async (t) => {
const browseExists = elements.browseButton.exists;
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
await t.useRole(roles.bucketRead).expect(browseExists).ok();
});

test("Bucket access is set to R", async (t) => {
await t.expect(elements.bucketAccessText.innerText).eql("Access: R");
});

test
.before(async (t) => {
await t
.useRole(roles.admin)
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
// Upload object to bucket
.setFilesToUpload(elements.uploadInput, "../uploads/test.txt")
.click(elements.logoutItem);
})("Object list table is enabled", async (t) => {
const bucketsTableExists = elements.table.exists;
await t
.useRole(roles.bucketRead)
.click(elements.browseButton)
.expect(bucketsTableExists)
.ok();
})
.after(async (t) => {
// Cleanup created bucket and corresponding uploads
await functions.cleanUpBucketAndUploads(t);
});
80 changes: 80 additions & 0 deletions portal-ui/tests/permissions/bucketWrite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import * as roles from "../utils/roles";
import * as elements from "../utils/elements";
import * as functions from "../utils/functions";

fixture("For user with Bucket Write permissions")
.page("http://localhost:5005")
.beforeEach(async (t) => {
await t.useRole(roles.bucketWrite);
});

test("Buckets sidebar item exists", async (t) => {
const bucketsExist = elements.bucketsElement.with({ boundTestRun: t }).exists;
await t.expect(bucketsExist).ok();
});

test.before(async (t) => {
// Create a bucket
await functions.setUpBucket(t);
})("Browse button exists", async (t) => {
const browseExists = elements.browseButton.exists;
await t
// We need to log back in after we use the admin account to create bucket,
// using the specific role we use in this module
.useRole(roles.bucketWrite)
.navigateTo("http://localhost:5005/buckets")
.expect(browseExists)
.ok();
});

test("Bucket access is set to W", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.expect(elements.bucketAccessText.innerText)
.eql("Access: W");
});

test("Upload button exists", async (t) => {
const uploadExists = elements.uploadButton.exists;
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
.expect(uploadExists)
.ok();
});

test("Object can be uploaded to a bucket", async (t) => {
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
// Upload object to bucket
.setFilesToUpload(elements.uploadInput, "../uploads/test.txt");
});

test("Object list table is disabled", async (t) => {
const disabledBucketsTableExists = elements.bucketsTableDisabled.exists;
await t
.navigateTo("http://localhost:5005/buckets")
.click(elements.browseButton)
.expect(disabledBucketsTableExists)
.ok();
}).after(async (t) => {
// Cleanup created bucket and corresponding uploads
await functions.cleanUpBucketAndUploads(t);
});
Loading