diff --git a/browser/app/js/objects/__tests__/actions.test.js b/browser/app/js/objects/__tests__/actions.test.js
index eba5a65ab..fb48b1dbc 100644
--- a/browser/app/js/objects/__tests__/actions.test.js
+++ b/browser/app/js/objects/__tests__/actions.test.js
@@ -19,16 +19,27 @@ import thunk from "redux-thunk"
import * as actionsObjects from "../actions"
import * as alertActions from "../../alert/actions"
import { minioBrowserPrefix } from "../../constants"
+import history from "../../history"
jest.mock("../../web", () => ({
- LoggedIn: jest.fn(() => true).mockReturnValueOnce(false),
- ListObjects: jest.fn(() => {
- return Promise.resolve({
- objects: [{ name: "test1" }, { name: "test2" }],
- istruncated: false,
- nextmarker: "test2",
- writable: false
- })
+ LoggedIn: jest
+ .fn(() => true)
+ .mockReturnValueOnce(true)
+ .mockReturnValueOnce(false)
+ .mockReturnValueOnce(false),
+ ListObjects: jest.fn(({ bucketName }) => {
+ if (bucketName === "test-deny") {
+ return Promise.reject({
+ message: "listobjects is denied"
+ })
+ } else {
+ return Promise.resolve({
+ objects: [{ name: "test1" }, { name: "test2" }],
+ istruncated: false,
+ nextmarker: "test2",
+ writable: false
+ })
+ }
}),
RemoveObject: jest.fn(({ bucketName, objects }) => {
if (!bucketName) {
@@ -112,6 +123,9 @@ describe("Objects actions", () => {
objects: { currentPrefix: "" }
})
const expectedActions = [
+ {
+ type: "alert/CLEAR"
+ },
{
type: "objects/SET_LIST",
objects: [{ name: "test1" }, { name: "test2" }],
@@ -143,6 +157,9 @@ describe("Objects actions", () => {
objects: { currentPrefix: "" }
})
const expectedActions = [
+ {
+ type: "alert/CLEAR"
+ },
{
type: "objects/APPEND_LIST",
objects: [{ name: "test1" }, { name: "test2" }],
@@ -160,6 +177,43 @@ describe("Objects actions", () => {
})
})
+ it("creates objects/RESET_LIST after failing to fetch the objects from bucket with ListObjects denied for LoggedIn users", () => {
+ const store = mockStore({
+ buckets: { currentBucket: "test-deny" },
+ objects: { currentPrefix: "" }
+ })
+ const expectedActions = [
+ {
+ type: "alert/CLEAR"
+ },
+ {
+ type: "alert/SET",
+ alert: {
+ type: "danger",
+ message: "listobjects is denied",
+ id: alertActions.alertId
+ }
+ },
+ {
+ type: "object/RESET_LIST"
+ }
+ ]
+ return store.dispatch(actionsObjects.fetchObjects()).then(() => {
+ const actions = store.getActions()
+ expect(actions).toEqual(expectedActions)
+ })
+ })
+
+ it("redirect to login after failing to fetch the objects from bucket for non-LoggedIn users", () => {
+ const store = mockStore({
+ buckets: { currentBucket: "test-deny" },
+ objects: { currentPrefix: "" }
+ })
+ return store.dispatch(actionsObjects.fetchObjects()).then(() => {
+ expect(history.location.pathname.endsWith("/login")).toBeTruthy()
+ })
+ })
+
it("creates objects/SET_SORT_BY and objects/SET_SORT_ORDER when sortObjects is called", () => {
const store = mockStore({
objects: {
@@ -198,6 +252,7 @@ describe("Objects actions", () => {
})
const expectedActions = [
{ type: "objects/SET_CURRENT_PREFIX", prefix: "abc/" },
+ { type: "alert/CLEAR" },
{ type: "objects/CHECKED_LIST_RESET" }
]
store.dispatch(actionsObjects.selectPrefix("abc/"))
@@ -244,7 +299,11 @@ describe("Objects actions", () => {
const expectedActions = [
{
type: "alert/SET",
- alert: { type: "danger", message: "Invalid bucket", id: 0 }
+ alert: {
+ type: "danger",
+ message: "Invalid bucket",
+ id: alertActions.alertId
+ }
}
]
return store.dispatch(actionsObjects.deleteObject("obj1")).then(() => {
diff --git a/browser/app/js/objects/actions.js b/browser/app/js/objects/actions.js
index e24832dcf..c4d2a3e2f 100644
--- a/browser/app/js/objects/actions.js
+++ b/browser/app/js/objects/actions.js
@@ -24,9 +24,11 @@ import {
import { getCurrentBucket } from "../buckets/selectors"
import { getCurrentPrefix, getCheckedList } from "./selectors"
import * as alertActions from "../alert/actions"
+import * as bucketActions from "../buckets/actions"
import { minioBrowserPrefix } from "../constants"
export const SET_LIST = "objects/SET_LIST"
+export const RESET_LIST = "object/RESET_LIST"
export const APPEND_LIST = "objects/APPEND_LIST"
export const REMOVE = "objects/REMOVE"
export const SET_SORT_BY = "objects/SET_SORT_BY"
@@ -45,6 +47,10 @@ export const setList = (objects, marker, isTruncated) => ({
isTruncated
})
+export const resetList = () => ({
+ type: RESET_LIST
+})
+
export const appendList = (objects, marker, isTruncated) => ({
type: APPEND_LIST,
objects,
@@ -58,6 +64,7 @@ export const fetchObjects = append => {
buckets: { currentBucket },
objects: { currentPrefix, marker }
} = getState()
+ dispatch(alertActions.clear())
if (currentBucket) {
return web
.ListObjects({
@@ -85,8 +92,13 @@ export const fetchObjects = append => {
dispatch(setPrefixWritable(res.writable))
})
.catch(err => {
- dispatch(alertActions.set({ type: "danger", message: err.message }))
- history.push("/login")
+ if (web.LoggedIn()) {
+ dispatch(alertActions.set({ type: "danger", message: err.message }))
+ dispatch(resetList())
+ }
+ else {
+ history.push("/login")
+ }
})
}
}
diff --git a/browser/app/js/objects/reducer.js b/browser/app/js/objects/reducer.js
index 1eab6a7b7..8b9888dc3 100644
--- a/browser/app/js/objects/reducer.js
+++ b/browser/app/js/objects/reducer.js
@@ -50,6 +50,13 @@ export default (
marker: action.marker,
isTruncated: action.isTruncated
}
+ case actionsObjects.RESET_LIST:
+ return {
+ ...state,
+ list: [],
+ marker: "",
+ isTruncated: false
+ }
case actionsObjects.APPEND_LIST:
return {
...state,
diff --git a/browser/ui-assets.go b/browser/ui-assets.go
index 036d935bf..9c8c6eaae 100644
--- a/browser/ui-assets.go
+++ b/browser/ui-assets.go
@@ -4,7 +4,7 @@
// production/favicon.ico
// production/firefox.png
// production/index.html
-// production/index_bundle-2018-08-24T02-51-30Z.js
+// production/index_bundle-2018-09-03T07-40-35Z.js
// production/loader.css
// production/logo.svg
// production/safari.png
@@ -14,6 +14,7 @@ package browser
import (
"fmt"
+ "github.com/elazarl/go-bindata-assetfs"
"io/ioutil"
"os"
"path/filepath"
@@ -64,7 +65,7 @@ func productionChromePng() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(420), modTime: time.Unix(1535079106, 0)}
+ info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(420), modTime: time.Unix(1535960452, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -81,7 +82,7 @@ func productionFaviconIco() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "production/favicon.ico", size: 501, mode: os.FileMode(420), modTime: time.Unix(1535079106, 0)}
+ info := bindataFileInfo{name: "production/favicon.ico", size: 501, mode: os.FileMode(420), modTime: time.Unix(1535960452, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -98,7 +99,7 @@ func productionFirefoxPng() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(420), modTime: time.Unix(1535079106, 0)}
+ info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(420), modTime: time.Unix(1535960452, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -155,8 +156,8 @@ var _productionIndexHTML = []byte(`
-
-
+
+