fix(state_mgr): support visitor to access sharing

This commit is contained in:
hexxa 2021-09-23 21:31:44 +08:00 committed by Hexxa
parent d6495a90ad
commit d440cbe477
4 changed files with 130 additions and 62 deletions

View file

@ -3,6 +3,10 @@ import axios, { AxiosRequestConfig } from "axios";
export const defaultTimeout = 10000; export const defaultTimeout = 10000;
export const userIDParam = "uid"; export const userIDParam = "uid";
export const roleAdmin = "admin";
export const roleUser = "user";
export const roleVisitor = "visitor";
export interface Quota { export interface Quota {
spaceLimit: string; spaceLimit: string;
uploadSpeedLimit: number; uploadSpeedLimit: number;

View file

@ -9,7 +9,7 @@ import { ICoreState, newWithWorker } from "../core_state";
import { MockWorker, UploadState, UploadEntry } from "../../worker/interface"; import { MockWorker, UploadState, UploadEntry } from "../../worker/interface";
describe("State Manager", () => { describe("State Manager", () => {
test("initUpdater", async () => { test("initUpdater for admin", async () => {
const usersCl = new MockUsersClient(""); const usersCl = new MockUsersClient("");
const filesCl = new MockFilesClient(""); const filesCl = new MockFilesClient("");
@ -36,16 +36,18 @@ describe("State Manager", () => {
); );
expect(coreState.browser.uploadings).toEqual( expect(coreState.browser.uploadings).toEqual(
List<UploadEntry>( List<UploadEntry>(
filesResps.listUploadingsMockResp.data.uploadInfos.map((info: UploadInfo) => { filesResps.listUploadingsMockResp.data.uploadInfos.map(
return { (info: UploadInfo) => {
file: undefined, return {
filePath: info.realFilePath, file: undefined,
size: info.size, filePath: info.realFilePath,
uploaded: info.uploaded, size: info.size,
state: UploadState.Ready, uploaded: info.uploaded,
err: "", state: UploadState.Ready,
}; err: "",
}) };
}
)
) )
); );
@ -71,7 +73,7 @@ describe("State Manager", () => {
downloadSpeedLimit: 3, downloadSpeedLimit: 3,
}, },
authed: true, authed: true,
captchaID: "mockCaptchaID", captchaID: "",
}); });
// admin // admin
@ -90,4 +92,77 @@ describe("State Manager", () => {
roles: roles, roles: roles,
}); });
}); });
test("initUpdater for visitor in sharing mode", async () => {
const usersCl = new MockUsersClient("");
const filesCl = new MockFilesClient("");
const mockSelfResp = {
status: 200,
statusText: "",
data: {
id: "-1",
name: "visitor",
role: "visitor",
usedSpace: "0",
quota: {
spaceLimit: "0",
uploadSpeedLimit: 0,
downloadSpeedLimit: 0,
},
},
};
const mockIsAuthedResp = { status: 401, statusText: "", data: {} };
const mockUserResps = {
...usersResps,
isAuthedMockResp: mockIsAuthedResp,
selfMockResp: mockSelfResp,
};
usersCl.setMock(mockUserResps);
const mockWorkerClass = mock(MockWorker);
const mockWorker = instance(mockWorkerClass);
const coreState = newWithWorker(mockWorker);
const mgr = new StateMgr({}); // it will call initUpdater
mgr.setUsersClient(usersCl);
mgr.setFilesClient(filesCl);
// TODO: depress warning
mgr.update = (apply: (prevState: ICoreState) => ICoreState): void => {
// no op
};
await mgr.initUpdater(coreState);
// browser
// TODO: mock query to get dir parm
expect(coreState.browser.dirPath.join("/")).toEqual("mock_home/files");
expect(coreState.browser.isSharing).toEqual(true);
expect(coreState.browser.sharings).toEqual(List([]));
expect(coreState.browser.uploadings).toEqual(List<UploadEntry>([]));
expect(coreState.browser.items).toEqual(
List(filesResps.listHomeMockResp.data.metadatas)
);
// panes
expect(coreState.panes).toEqual({
displaying: "",
paneNames: Set(["settings", "login", "admin"]),
});
// login
expect(coreState.login).toEqual({
userID: mockSelfResp.data.id,
userName: mockSelfResp.data.name,
userRole: mockSelfResp.data.role,
quota: mockSelfResp.data.quota,
usedSpace: mockSelfResp.data.usedSpace,
authed: false,
captchaID: "",
});
// admin
expect(coreState.admin).toEqual({
users: Map({}),
roles: Set<string>(),
});
});
}); });

View file

@ -2,6 +2,7 @@ import * as React from "react";
import { Set, Map } from "immutable"; import { Set, Map } from "immutable";
import { updater } from "./state_updater"; import { updater } from "./state_updater";
import { roleAdmin, roleVisitor } from "../client";
import { ICoreState, MsgProps } from "./core_state"; import { ICoreState, MsgProps } from "./core_state";
import { PaneSettings } from "./pane_settings"; import { PaneSettings } from "./pane_settings";
import { AdminPane, AdminProps } from "./pane_admin"; import { AdminPane, AdminProps } from "./pane_admin";
@ -40,23 +41,25 @@ export class Panes extends React.Component<Props, State, {}> {
displaying = "login"; displaying = "login";
} }
let panesMap: Map<string, JSX.Element> = Map({ let panesMap: Map<string, JSX.Element> = Map({});
settings: ( if (this.props.login.userRole !== roleVisitor) {
panesMap = panesMap.set(
"settings",
<PaneSettings <PaneSettings
login={this.props.login} login={this.props.login}
msg={this.props.msg} msg={this.props.msg}
update={this.props.update} update={this.props.update}
/> />
), );
login: ( panesMap = panesMap.set(
"login",
<AuthPane <AuthPane
login={this.props.login} login={this.props.login}
update={this.props.update} update={this.props.update}
msg={this.props.msg} msg={this.props.msg}
/> />
), );
}); }
if (this.props.login.userRole === "admin") { if (this.props.login.userRole === "admin") {
panesMap = panesMap.set( panesMap = panesMap.set(
"admin", "admin",

View file

@ -6,7 +6,7 @@ import { ICoreState, newState } from "./core_state";
import { RootFrame } from "./root_frame"; import { RootFrame } from "./root_frame";
import { FilesClient } from "../client/files"; import { FilesClient } from "../client/files";
import { UsersClient } from "../client/users"; import { UsersClient } from "../client/users";
import { IUsersClient, IFilesClient } from "../client"; import { IUsersClient, IFilesClient, roleAdmin, roleVisitor } from "../client";
import { alertMsg } from "../common/env"; import { alertMsg } from "../common/env";
export interface Props {} export interface Props {}
@ -39,30 +39,11 @@ export class StateMgr extends React.Component<Props, State, {}> {
updater().setClients(this.usersClient, this.filesClient); updater().setClients(this.usersClient, this.filesClient);
const params = new URLSearchParams(document.location.search.substring(1)); const params = new URLSearchParams(document.location.search.substring(1));
return updater() return updater()
.initIsAuthed() .initIsAuthed()
.then(() => { .then(() => {
this.update(updater().updateLogin); return updater().self();
})
.then(() => {
if (updater().props.login.authed) {
updater().displayPane("");
} else {
updater().displayPane("login");
}
})
.then(() => {
return updater().getCaptchaID();
})
.then((ok: boolean) => {
if (!ok) {
alertMsg(this.state.msg.pkg.get("stateMgr.cap.fail"));
} else {
this.update(updater().updateLogin);
}
})
.then(() => {
return updater().refreshUploadings();
}) })
.then(() => { .then(() => {
const dir = params.get("dir"); const dir = params.get("dir");
@ -73,34 +54,39 @@ export class StateMgr extends React.Component<Props, State, {}> {
return updater().setHomeItems(); return updater().setHomeItems();
} }
}) })
.then(() => {
return updater().initUploads();
})
.then(() => { .then(() => {
return updater().isSharing(updater().props.browser.dirPath.join("/")); return updater().isSharing(updater().props.browser.dirPath.join("/"));
}) })
.then(() => { .then(() => {
return updater().listSharings(); // init browser content
if (updater().props.login.userRole === roleVisitor) {
if (updater().props.browser.isSharing) {
// sharing with visitor
updater().displayPane("");
return Promise.all([]);
}
// redirect to login
updater().displayPane("login");
return Promise.all([updater().getCaptchaID()]);
}
updater().displayPane("");
return Promise.all([
updater().refreshUploadings(),
updater().initUploads(),
updater().listSharings(),
]);
})
.then(() => {
// init admin content
if (updater().props.login.userRole === roleAdmin) {
return Promise.all([updater().listRoles(), updater().listUsers()]);
}
return;
}) })
.then(() => { .then(() => {
this.update(updater().updateBrowser); this.update(updater().updateBrowser);
})
.then(() => {
return updater().self();
})
.then(() => {
if (updater().props.login.userRole === "admin") {
// TODO: remove hardcode
return updater().listRoles();
}
})
.then(() => {
if (updater().props.login.userRole === "admin") {
// TODO: remove hardcode
return updater().listUsers();
}
})
.then(() => {
this.update(updater().updateLogin); this.update(updater().updateLogin);
this.update(updater().updatePanes); this.update(updater().updatePanes);
this.update(updater().updateAdmin); this.update(updater().updateAdmin);