Skip to content
This repository was archived by the owner on Dec 18, 2023. It is now read-only.

Commit 43b33a6

Browse files
committed
Allow paritytech member to see resources
1 parent ce0a16e commit 43b33a6

File tree

6 files changed

+102
-66
lines changed

6 files changed

+102
-66
lines changed

backend/src/api.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub fn get_user(
122122
id: String,
123123
) -> Result<JsonValue, status::Unauthorized<()>> {
124124
let manager = state.manager.clone();
125-
if user.admin {
125+
if user.has_admin_read_rights() {
126126
Ok(result_to_jsonrpc(manager.get_user(&id)))
127127
} else {
128128
Err(status::Unauthorized::<()>(None))
@@ -135,7 +135,7 @@ pub fn list_users(
135135
user: LoggedUser,
136136
) -> Result<JsonValue, status::Unauthorized<()>> {
137137
let manager = state.manager.clone();
138-
if user.admin {
138+
if user.has_admin_read_rights() {
139139
Ok(result_to_jsonrpc(manager.list_users()))
140140
} else {
141141
Err(status::Unauthorized::<()>(None))
@@ -150,7 +150,7 @@ pub fn create_user(
150150
conf: Json<UserConfiguration>,
151151
) -> Result<JsonValue, status::Unauthorized<()>> {
152152
let manager = state.manager.clone();
153-
if user.admin {
153+
if user.has_admin_edit_rights() {
154154
Ok(result_to_jsonrpc(manager.create_user(id, conf.0)))
155155
} else {
156156
Err(status::Unauthorized::<()>(None))
@@ -165,7 +165,7 @@ pub fn update_user(
165165
conf: Json<UserUpdateConfiguration>,
166166
) -> Result<JsonValue, status::Unauthorized<()>> {
167167
let manager = state.manager.clone();
168-
if user.admin {
168+
if user.has_admin_edit_rights() {
169169
Ok(result_to_jsonrpc(manager.update_user(id, conf.0)))
170170
} else {
171171
Err(status::Unauthorized::<()>(None))
@@ -179,7 +179,7 @@ pub fn delete_user(
179179
id: String,
180180
) -> Result<JsonValue, status::Unauthorized<()>> {
181181
let manager = state.manager.clone();
182-
if user.admin {
182+
if user.has_admin_edit_rights() {
183183
Ok(result_to_jsonrpc(manager.delete_user(id)))
184184
} else {
185185
Err(status::Unauthorized::<()>(None))
@@ -253,7 +253,7 @@ pub fn get_session(
253253
id: String,
254254
) -> Result<JsonValue, status::Unauthorized<()>> {
255255
let manager = state.manager.clone();
256-
if user.admin {
256+
if user.has_admin_read_rights() {
257257
Ok(result_to_jsonrpc(manager.get_session(&id)))
258258
} else {
259259
Err(status::Unauthorized::<()>(None))
@@ -266,7 +266,7 @@ pub fn list_sessions(
266266
user: LoggedUser,
267267
) -> Result<JsonValue, status::Unauthorized<()>> {
268268
let manager = state.manager.clone();
269-
if user.admin {
269+
if user.has_admin_read_rights() {
270270
Ok(result_to_jsonrpc(manager.list_sessions()))
271271
} else {
272272
Err(status::Unauthorized::<()>(None))
@@ -281,7 +281,7 @@ pub fn create_session(
281281
conf: Json<SessionConfiguration>,
282282
) -> Result<JsonValue, status::Unauthorized<()>> {
283283
let manager = state.manager.clone();
284-
if user.admin {
284+
if user.has_admin_edit_rights() {
285285
Ok(result_to_jsonrpc(
286286
manager.create_session(&id, &user, conf.0),
287287
))
@@ -298,7 +298,7 @@ pub fn update_session(
298298
conf: Json<SessionUpdateConfiguration>,
299299
) -> Result<JsonValue, status::Unauthorized<()>> {
300300
let manager = state.manager.clone();
301-
if user.admin {
301+
if user.has_admin_edit_rights() {
302302
Ok(result_to_jsonrpc(
303303
manager.update_session(&id, &user, conf.0),
304304
))
@@ -314,7 +314,7 @@ pub fn delete_session(
314314
id: String,
315315
) -> Result<JsonValue, status::Unauthorized<()>> {
316316
let manager = state.manager.clone();
317-
if user.admin {
317+
if user.has_admin_edit_rights() {
318318
Ok(result_to_jsonrpc(manager.delete_session(&id)))
319319
} else {
320320
Err(status::Unauthorized::<()>(None))
@@ -330,7 +330,7 @@ pub fn get_pool(
330330
id: String,
331331
) -> Result<JsonValue, status::Unauthorized<()>> {
332332
let manager = state.manager.clone();
333-
if user.admin {
333+
if user.has_admin_read_rights() {
334334
Ok(result_to_jsonrpc(manager.get_pool(&id)))
335335
} else {
336336
Err(status::Unauthorized::<()>(None))
@@ -343,7 +343,7 @@ pub fn list_pools(
343343
user: LoggedUser,
344344
) -> Result<JsonValue, status::Unauthorized<()>> {
345345
let manager = state.manager.clone();
346-
if user.admin {
346+
if user.has_admin_read_rights() {
347347
Ok(result_to_jsonrpc(manager.list_pools()))
348348
} else {
349349
Err(status::Unauthorized::<()>(None))

backend/src/manager.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -206,17 +206,6 @@ impl Manager {
206206
new_runtime()?.block_on(self.clone().engine.list_sessions())
207207
}
208208

209-
fn paritytech_member(&self, user: &LoggedUser) -> bool {
210-
user.organizations.contains(&"paritytech".to_string())
211-
}
212-
fn can_customize_duration(&self, user: &LoggedUser) -> bool {
213-
user.admin || user.can_customize_duration || self.paritytech_member(user)
214-
}
215-
216-
fn can_customize_pool_affinity(&self, user: &LoggedUser) -> bool {
217-
user.admin || user.can_customize_pool_affinity || self.paritytech_member(user)
218-
}
219-
220209
pub fn create_session(
221210
self,
222211
id: &str,
@@ -225,13 +214,13 @@ impl Manager {
225214
) -> Result<(), String> {
226215
if conf.duration.is_some() {
227216
// Duration can only customized by users with proper rights
228-
if !self.can_customize_duration(user) {
217+
if !user.can_customize_duration() {
229218
return Err("Only admin can customize a session duration".to_string());
230219
}
231220
}
232221
if conf.pool_affinity.is_some() {
233222
// Duration can only customized by users with proper rights
234-
if !self.can_customize_pool_affinity(user) {
223+
if !user.can_customize_pool_affinity() {
235224
return Err("Only admin can customize a session pool affinity".to_string());
236225
}
237226
}
@@ -261,7 +250,7 @@ impl Manager {
261250
) -> Result<(), String> {
262251
if conf.duration.is_some() {
263252
// Duration can only customized by users with proper rights
264-
if !self.can_customize_duration(user) {
253+
if !user.can_customize_duration() {
265254
return Err("Only admin can customize a session duration".to_string());
266255
}
267256
}

backend/src/types.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,29 @@ pub struct LoggedUser {
132132
pub can_customize_pool_affinity: bool,
133133
}
134134

135+
impl LoggedUser {
136+
137+
pub fn is_paritytech_member(&self) -> bool {
138+
self.organizations.contains(&"paritytech".to_string())
139+
}
140+
pub fn can_customize_duration(&self) -> bool {
141+
self.admin || self.can_customize_duration || self.is_paritytech_member()
142+
}
143+
144+
pub fn can_customize_pool_affinity(&self) -> bool {
145+
self.admin || self.can_customize_pool_affinity || self.is_paritytech_member()
146+
}
147+
148+
pub fn has_admin_read_rights(&self) -> bool {
149+
self.admin || self.is_paritytech_member()
150+
}
151+
152+
pub fn has_admin_edit_rights(&self) -> bool {
153+
self.admin
154+
}
155+
156+
}
157+
135158
#[derive(Serialize, Deserialize, Clone, Debug)]
136159
pub struct Template {
137160
pub name: String,

frontend/src/components.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Typography from '@material-ui/core/Typography';
2121
import { Configuration, LoggedUser } from "@substrate/playground-client";
2222
import { useInterval } from './hooks';
2323
import { Params } from "./index";
24+
import { hasAdminReadRights } from './utils';
2425

2526
function wrapAction(action: (() => void) | Promise<void>, call: (flag: boolean) => void):(() => void) | Promise<void> {
2627
if (action instanceof Promise) {
@@ -156,7 +157,7 @@ function Nav({ conf, onPlayground, onStatsClick, onAdminClick, onLogout, user }:
156157
<Button onClick={onPlayground}>Playground</Button>
157158
</Typography>
158159
<div style={{display: "flex", alignItems: "center"}}>
159-
{user?.admin &&
160+
{(user && hasAdminReadRights(user)) &&
160161
<div style={{paddingLeft: 12}}>
161162
<IconButton
162163
aria-label="account of current user"

frontend/src/panels/admin.tsx

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Typography from '@material-ui/core/Typography';
2929
import { Client, Configuration, LoggedUser, Pool, Session, SessionConfiguration, SessionUpdateConfiguration, Template, User, UserConfiguration, UserUpdateConfiguration } from '@substrate/playground-client';
3030
import { CenteredContainer, ErrorSnackbar, LoadingPanel } from '../components';
3131
import { useInterval } from '../hooks';
32+
import { canCustomizeDuration, canCustomizePoolAffinity, hasAdminEditRights, hasAdminReadRights } from '../utils';
3233
import { DialogActions, DialogContentText, MenuItem } from '@material-ui/core';
3334
import { Autocomplete } from '@material-ui/lab';
3435

@@ -38,12 +39,12 @@ const useStyles = makeStyles({
3839
},
3940
});
4041

41-
function NoResourcesContainer({ label, action }: { label: string, action?: () => void}): JSX.Element {
42+
function NoResourcesContainer({ user, label, action }: { user: LoggedUser, label: string, action?: () => void}): JSX.Element {
4243
return (
4344
<Container>
4445
<Typography variant="h6">
4546
{label}
46-
{action &&
47+
{(action && hasAdminEditRights(user)) &&
4748
<Tooltip title="Create">
4849
<IconButton aria-label="create" onClick={action}>
4950
<AddIcon />
@@ -77,18 +78,6 @@ function Resources<T>( { children, label, callback }: { children: (resources: Re
7778
}
7879
}
7980

80-
function paritytechMember(user: LoggedUser): boolean {
81-
return user.organizations.indexOf('paritytech') != -1;
82-
}
83-
84-
function canCustomizeDuration(user: LoggedUser): boolean {
85-
return user.admin || user.canCustomizeDuration || paritytechMember(user);
86-
}
87-
88-
function canCustomizePoolAffinity(user: LoggedUser): boolean {
89-
return user.admin || user.canCustomizePoolAffinity || paritytechMember(user);
90-
}
91-
9281
export function canCustomize(user: LoggedUser): boolean {
9382
return canCustomizeDuration(user) || canCustomizePoolAffinity(user);
9483
}
@@ -327,7 +316,7 @@ function Sessions({ client, conf, user }: { client: Client, conf: Configuration,
327316
{Object.keys(resources).length > 0
328317
?
329318
<>
330-
<EnhancedTableToolbar label="Sessions" selected={selected} onCreate={() => setShowCreationDialog(true)} onUpdate={() => setShowUpdateDialog(true)} onDelete={() => onDelete(setSessions)} />
319+
<EnhancedTableToolbar user={user} label="Sessions" selected={selected} onCreate={() => setShowCreationDialog(true)} onUpdate={() => setShowUpdateDialog(true)} onDelete={() => onDelete(setSessions)} />
331320
<TableContainer component={Paper}>
332321
<Table className={classes.table} aria-label="simple table">
333322
<TableHead>
@@ -374,7 +363,7 @@ function Sessions({ client, conf, user }: { client: Client, conf: Configuration,
374363
</Table>
375364
</TableContainer>
376365
</>
377-
: <NoResourcesContainer label={`No sessions`} action={() => setShowCreationDialog(true)} />}
366+
: <NoResourcesContainer user={user} label="No sessions" action={() => setShowCreationDialog(true)} />}
378367
{errorMessage &&
379368
<ErrorSnackbar open={true} message={errorMessage} onClose={() => setErrorMessage(null)} />}
380369
<SessionCreationDialog allowUserSelection={true} client={client} conf={conf} sessions={resources} user={user} users={users} templates={templates} show={showCreationDialog} onCreate={(conf, id) => onCreate(conf, id, setSessions)} onHide={() => setShowCreationDialog(false)} />
@@ -386,14 +375,14 @@ function Sessions({ client, conf, user }: { client: Client, conf: Configuration,
386375
);
387376
}
388377

389-
function Templates({ client }: { client: Client }): JSX.Element {
378+
function Templates({ client, user }: { client: Client, user: LoggedUser }): JSX.Element {
390379
const classes = useStyles();
391380

392381
return (
393382
<Resources<Template> label="Templates" callback={async () => (await client.get()).templates}>
394383
{(resources: Record<string, Template>) => (
395384
<>
396-
<EnhancedTableToolbar label="Templates" />
385+
<EnhancedTableToolbar user={user} label="Templates" />
397386
<TableContainer component={Paper}>
398387
<Table className={classes.table} aria-label="simple table">
399388
<TableHead>
@@ -474,20 +463,10 @@ function DeleteConfirmationDialog({open, onClose, onConfirmation}: {open: boolea
474463
);
475464
}
476465

477-
function EnhancedTableToolbar({ label, selected = null, onCreate, onUpdate, onDelete }: { label: string, selected?: string | null, onCreate?: () => void, onUpdate?: () => void, onDelete?: () => void}): JSX.Element {
466+
function EditToolbar({ selected, onCreate, onUpdate, onDelete }: {selected?: string | null, onCreate?: () => void, onUpdate?: () => void, onDelete?: () => void}): JSX.Element {
478467
const [open, setOpen] = React.useState(false);
479-
const classes = useToolbarStyles();
480-
return (
481-
<>
482-
<Toolbar
483-
className={clsx(classes.root, {
484-
[classes.highlight]: selected != null,
485-
})}
486-
>
487-
<Typography className={classes.title} variant="h6" id="tableTitle" component="div">
488-
{label}
489-
</Typography>
490-
{selected ?
468+
if (selected) {
469+
return (
491470
<>
492471
{onUpdate &&
493472
<Tooltip title="Update">
@@ -503,15 +482,35 @@ function EnhancedTableToolbar({ label, selected = null, onCreate, onUpdate, onDe
503482
</Tooltip>}
504483
<DeleteConfirmationDialog open={open} onClose={() => setOpen(false)} onConfirmation={onDelete} />
505484
</>
506-
: <>
485+
);
486+
} else {
487+
return (
488+
<>
507489
{onCreate &&
508490
<Tooltip title="Create">
509491
<IconButton aria-label="create" onClick={onCreate}>
510492
<AddIcon />
511493
</IconButton>
512494
</Tooltip>}
513495
</>
514-
}
496+
);
497+
}
498+
}
499+
500+
function EnhancedTableToolbar({ user, label, selected = null, onCreate, onUpdate, onDelete }: { user: LoggedUser, label: string, selected?: string | null, onCreate?: () => void, onUpdate?: () => void, onDelete?: () => void}): JSX.Element {
501+
const classes = useToolbarStyles();
502+
return (
503+
<>
504+
<Toolbar
505+
className={clsx(classes.root, {
506+
[classes.highlight]: selected != null,
507+
})}
508+
>
509+
<Typography className={classes.title} variant="h6" id="tableTitle" component="div">
510+
{label}
511+
</Typography>
512+
{hasAdminEditRights(user) &&
513+
<EditToolbar selected={selected} onCreate={onCreate} onUpdate={onUpdate} onDelete={onDelete} />}
515514
</Toolbar>
516515
</>
517516
);
@@ -747,7 +746,7 @@ function Users({ client, user, conf }: { client: Client, user: LoggedUser, conf:
747746
<Resources<User> label="Users" callback={async () => await client.listUsers()}>
748747
{(resources: Record<string, User>, setUsers: Dispatch<SetStateAction<Record<string, User> | null>>) => (
749748
<>
750-
<EnhancedTableToolbar label="Users" selected={selected} onCreate={() => setShowCreationDialog(true)} onUpdate={() => setShowUpdateDialog(true)} onDelete={() => onDelete(setUsers)} />
749+
<EnhancedTableToolbar user={user} label="Users" selected={selected} onCreate={() => setShowCreationDialog(true)} onUpdate={() => setShowUpdateDialog(true)} onDelete={() => onDelete(setUsers)} />
751750
<TableContainer component={Paper}>
752751
<Table className={classes.table} aria-label="simple table">
753752
<TableHead>
@@ -839,14 +838,14 @@ function DetailsPanel({ conf }: { conf: Configuration }): JSX.Element {
839838
);
840839
}
841840

842-
function Pools({ client }: { client: Client }): JSX.Element {
841+
function Pools({ client, user }: { client: Client, user: LoggedUser }): JSX.Element {
843842
const classes = useStyles();
844843

845844
return (
846845
<Resources<Pool> label="Pools" callback={async () => await client.listPools()}>
847846
{(resources: Record<string, Pool>) => (
848847
<>
849-
<EnhancedTableToolbar label="Pools" />
848+
<EnhancedTableToolbar user={user} label="Pools" />
850849
<TableContainer component={Paper}>
851850
<Table className={classes.table} aria-label="simple table">
852851
<TableHead>
@@ -894,12 +893,12 @@ export function AdminPanel({ client, user, conf }: { client: Client, user: Logge
894893
{value == 0
895894
? <DetailsPanel conf={conf} />
896895
: value == 1
897-
? <Templates client={client} />
896+
? <Templates client={client} user={user} />
898897
: value == 2
899898
? <Users client={client} user={user} conf={conf} />
900899
: value == 3
901900
? <Sessions client={client} conf={conf} user={user} />
902-
: <Pools client={client} />}
901+
: <Pools client={client} user={user} />}
903902
</Paper>
904903
</CenteredContainer>
905904
);

0 commit comments

Comments
 (0)