added permissions logic
This commit is contained in:
parent
39860c84e6
commit
b25998da7f
171
src/actions.tsx
171
src/actions.tsx
@ -129,27 +129,6 @@ const definitions = {
|
||||
],
|
||||
title: "ImageInfo"
|
||||
},
|
||||
InviteUserRequests: {
|
||||
properties: {
|
||||
email: {
|
||||
type: "string",
|
||||
title: "Email"
|
||||
},
|
||||
permissions: {
|
||||
items: {
|
||||
"$ref": "#/definitions/Permission"
|
||||
},
|
||||
type: "array",
|
||||
title: "Permissions"
|
||||
}
|
||||
},
|
||||
type: "object",
|
||||
required: [
|
||||
"email",
|
||||
"permissions"
|
||||
],
|
||||
title: "InviteUserRequests"
|
||||
},
|
||||
PasswordRequestForm: {
|
||||
properties: {
|
||||
username: {
|
||||
@ -345,54 +324,6 @@ const definitions = {
|
||||
],
|
||||
title: "SetServerNicknameRequest"
|
||||
},
|
||||
SetServerPermissionsRequest: {
|
||||
properties: {
|
||||
username: {
|
||||
type: "string",
|
||||
title: "Username",
|
||||
fetch_display_path: "username",
|
||||
fetch_key_path: "username",
|
||||
fetch_url: "/users"
|
||||
},
|
||||
permissions: {
|
||||
items: {
|
||||
"$ref": "#/definitions/Permission"
|
||||
},
|
||||
type: "array",
|
||||
title: "Permissions"
|
||||
}
|
||||
},
|
||||
type: "object",
|
||||
required: [
|
||||
"username"
|
||||
],
|
||||
title: "SetServerPermissionsRequest"
|
||||
},
|
||||
StartServerRequest: {
|
||||
properties: {
|
||||
ports: {
|
||||
items: {
|
||||
"$ref": "#/definitions/PortMapping"
|
||||
},
|
||||
type: "array",
|
||||
title: "Ports",
|
||||
default: []
|
||||
},
|
||||
command: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "string"
|
||||
},
|
||||
{
|
||||
type: "null"
|
||||
}
|
||||
],
|
||||
title: "Command"
|
||||
}
|
||||
},
|
||||
type: "object",
|
||||
title: "StartServerRequest"
|
||||
},
|
||||
Token: {
|
||||
properties: {
|
||||
access_token: {
|
||||
@ -482,7 +413,29 @@ export const SERVER_ACTIONS: ActionInfo[] = [
|
||||
{
|
||||
name: "Start",
|
||||
args: {
|
||||
"$ref": "#/definitions/StartServerRequest",
|
||||
properties: {
|
||||
ports: {
|
||||
items: {
|
||||
"$ref": "#/definitions/PortMapping"
|
||||
},
|
||||
type: "array",
|
||||
title: "Ports",
|
||||
default: []
|
||||
},
|
||||
command: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "string"
|
||||
},
|
||||
{
|
||||
type: "null"
|
||||
}
|
||||
],
|
||||
title: "Command"
|
||||
}
|
||||
},
|
||||
type: "object",
|
||||
title: "Start Server",
|
||||
definitions: definitions,
|
||||
},
|
||||
requestType: "post",
|
||||
@ -554,27 +507,66 @@ export const SERVER_ACTIONS: ActionInfo[] = [
|
||||
response_action: "Browse"
|
||||
},
|
||||
{
|
||||
name: "Set Nickname",
|
||||
name: "Update Server",
|
||||
requestType: "patch",
|
||||
endpoint: "/servers/{server_id}",
|
||||
permissions: Permission.Admin,
|
||||
response_action: "Ignore",
|
||||
args: {
|
||||
"$ref": "#/definitions/SetServerNicknameRequest",
|
||||
title: "Update Server",
|
||||
type: "object",
|
||||
required: [],
|
||||
properties: {
|
||||
DefaultPorts: {
|
||||
type: "array",
|
||||
title: "Default Ports",
|
||||
items:
|
||||
{
|
||||
"$ref": "#/definitions/Port-Input"
|
||||
}
|
||||
|
||||
},
|
||||
DefaultCommand: {
|
||||
type: "string",
|
||||
title: "Default Command"
|
||||
},
|
||||
Nickname: {
|
||||
type: "string",
|
||||
title: "Nickname"
|
||||
}
|
||||
},
|
||||
definitions: definitions,
|
||||
|
||||
},
|
||||
requestType: "post",
|
||||
endpoint: "/servers/{server_id}/nickname",
|
||||
permissions: Permission.Admin,
|
||||
response_action: "Ignore"
|
||||
},
|
||||
{
|
||||
name: "Add Permissions",
|
||||
args: {
|
||||
"$ref": "#/definitions/SetServerPermissionsRequest",
|
||||
definitions: definitions,
|
||||
},
|
||||
requestType: "post",
|
||||
endpoint: "/servers/{server_id}/permissions",
|
||||
permissions: Permission.Admin,
|
||||
response_action: "Ignore"
|
||||
response_action: "Ignore",
|
||||
args: {
|
||||
properties: {
|
||||
username: {
|
||||
type: "string",
|
||||
title: "Username",
|
||||
fetch_display_path: "Username",
|
||||
fetch_key_path: "Username",
|
||||
fetch_url: "/users"
|
||||
},
|
||||
permissions: {
|
||||
type: "number",
|
||||
title: "Permissions",
|
||||
permissions: true,
|
||||
}
|
||||
},
|
||||
type: "object",
|
||||
required: [
|
||||
"username"
|
||||
],
|
||||
title: "Set User Permissions",
|
||||
definitions: definitions,
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
@ -622,7 +614,22 @@ export const CREATE_SERVER_ACTION: ActionInfo = {
|
||||
export const INVITE_USER_ACTION: ActionInfo = {
|
||||
name: "Invite User",
|
||||
args: {
|
||||
"$ref": "#/definitions/InviteUserRequests",
|
||||
properties: {
|
||||
email: {
|
||||
type: "string",
|
||||
title: "Email"
|
||||
},
|
||||
permissions: {
|
||||
type: "number",
|
||||
title: "Permissions",
|
||||
permissions: true,
|
||||
}
|
||||
},
|
||||
type: "object",
|
||||
required: [
|
||||
"email"
|
||||
],
|
||||
title: "Invite User",
|
||||
definitions: definitions,
|
||||
},
|
||||
requestType: "post",
|
||||
|
@ -6,8 +6,7 @@ import { Box, Button, ButtonGroup, ButtonOwnProps, Modal, PaletteMode, Paper, Ta
|
||||
import { Form } from "@rjsf/mui";
|
||||
import validator from '@rjsf/validator-ajv8';
|
||||
import { blue, grey } from "@mui/material/colors";
|
||||
import { OpenAPISchema, User } from "./interfaces";
|
||||
import { JSONSchema7 } from "json-schema";
|
||||
import { User } from "./interfaces";
|
||||
import { IChangeEvent } from "@rjsf/core";
|
||||
import { RJSFSchema, WidgetProps } from "@rjsf/utils";
|
||||
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
||||
@ -99,7 +98,7 @@ export function ApiWrapper(p: { children: ReactNode}) {
|
||||
|
||||
export interface ActionInfo {
|
||||
name: string
|
||||
requestType: 'post' | 'get' | 'delete'
|
||||
requestType: 'post' | 'get' | 'delete' | 'patch'
|
||||
endpoint: string
|
||||
args: {}
|
||||
permissions?: number
|
||||
@ -114,14 +113,61 @@ interface Options{
|
||||
|
||||
export const actionIdentifierContext: Context<string> = createContext('')
|
||||
|
||||
function FetcherField(props: WidgetProps){
|
||||
|
||||
function convertNumber(permissions: number): number[]{
|
||||
var arr: number[] = []
|
||||
if (permissions&Permission.Start){
|
||||
arr.push(Permission.Start)
|
||||
}
|
||||
if (permissions&Permission.Stop){
|
||||
arr.push(Permission.Stop)
|
||||
}
|
||||
if (permissions&Permission.Browse){
|
||||
arr.push(Permission.Browse)
|
||||
}
|
||||
if (permissions&Permission.RunCommand){
|
||||
arr.push(Permission.RunCommand)
|
||||
}
|
||||
if (permissions&Permission.Create){
|
||||
arr.push(Permission.Create)
|
||||
}
|
||||
if (permissions&Permission.Delete){
|
||||
arr.push(Permission.Delete)
|
||||
}
|
||||
if (permissions&Permission.Admin){
|
||||
arr.push(Permission.Admin)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
function CustomField(props: WidgetProps){
|
||||
const jp = require('jsonpath')
|
||||
const [options2, setOptions]: [Options[]|null, Dispatch<Options[]>] = useState(null as Options[]|null)
|
||||
const {schema, registry, options, ...newProps} = props
|
||||
const {SelectWidget} = registry.widgets
|
||||
const {SelectWidget, CheckboxesWidget} = registry.widgets
|
||||
|
||||
if (!schema.fetch_url){
|
||||
return <TextField onChange={(event)=>(props.onChange(event.target.value))} value={props.value} label={props.label}/>
|
||||
if (!schema.permissions){
|
||||
return <TextField onChange={(event)=>(props.onChange(event.target.value))} value={props.value} label={props.label}/>
|
||||
}
|
||||
|
||||
return <CheckboxesWidget
|
||||
{...newProps}
|
||||
onChange={(event)=>{
|
||||
props.onChange(event.reduce((partialSum: number, a: number) => (partialSum + a), 0))
|
||||
}
|
||||
}
|
||||
schema={{}}
|
||||
options={{
|
||||
enumOptions: [
|
||||
{label: 'Start', value: Permission.Start},
|
||||
{label: 'Stop', value: Permission.Stop},
|
||||
{label: 'Browse', value: Permission.Browse},
|
||||
{label: 'Delete', value: Permission.Delete},
|
||||
{label: 'RunCommand', value: Permission.RunCommand},
|
||||
{label: 'Create', value: Permission.Create},
|
||||
{label: 'Admin', value: Permission.Admin},
|
||||
]}} registry={registry} value={convertNumber(props.value)} />
|
||||
}
|
||||
|
||||
if (options2 === null){
|
||||
@ -142,7 +188,6 @@ function FetcherField(props: WidgetProps){
|
||||
|
||||
|
||||
function isUserAllowed(user: User|null, action: ActionInfo): boolean{
|
||||
console.log({User: user, Action: action})
|
||||
if (user === null){
|
||||
return false
|
||||
}
|
||||
@ -171,6 +216,7 @@ export function ActionItem(p: { action: ActionInfo, identifierSubstring?: string
|
||||
|
||||
const [form, setForm] = useState(false);
|
||||
const [formData, setFormData]: [RJSFSchema, Dispatch<RJSFSchema>] = useState({})
|
||||
console.log(formData)
|
||||
|
||||
|
||||
function handleSubmit() {
|
||||
@ -181,6 +227,10 @@ export function ActionItem(p: { action: ActionInfo, identifierSubstring?: string
|
||||
promise = api.post(url, formData)
|
||||
break
|
||||
}
|
||||
case 'patch':{
|
||||
promise = api.patch(url, formData)
|
||||
break
|
||||
}
|
||||
case 'get': {
|
||||
if (formData){
|
||||
console.warn('get can get no arguments, dropping')
|
||||
@ -218,7 +268,7 @@ export function ActionItem(p: { action: ActionInfo, identifierSubstring?: string
|
||||
open={form}
|
||||
>
|
||||
<Box sx={formModalStyle}>
|
||||
<Form validator={validator} widgets={{TextWidget: FetcherField}} schema={p.action.args} onChange={onFormChange} formData={formData} onSubmit={handleSubmit} />
|
||||
<Form validator={validator} widgets={{TextWidget: CustomField}} schema={p.action.args} onChange={onFormChange} formData={formData} onSubmit={handleSubmit} />
|
||||
</Box>
|
||||
</Modal>
|
||||
</>)
|
||||
@ -294,9 +344,6 @@ export function ActionGroup(p: { actions: ActionInfo[], identifierSubstring?: st
|
||||
<ClickAwayListener onClickAway={handleClose}>
|
||||
<MenuList id="split-button-menu" autoFocusItem>
|
||||
{actionItems.map((option, index) => {
|
||||
if (!option.props){
|
||||
console.log(actionItems)
|
||||
}
|
||||
return <MenuItem
|
||||
key={option.props.action.name}
|
||||
selected={index === selectedIndex}
|
||||
|
@ -48,7 +48,6 @@ function UserItem(p: { user: User }) {
|
||||
export function UsersPage({ }) {
|
||||
const [apiAuthenticated, setApiAuthenticated] = useContext(apiAuthenticatedContext)
|
||||
const [users, setUsers]: [User[], Dispatch<User[]>] = useState([] as User[])
|
||||
console.log({apiAuthenticated: apiAuthenticated, users: users})
|
||||
|
||||
const action: ActionInfo|undefined = INVITE_USER_ACTION
|
||||
|
||||
@ -60,7 +59,7 @@ export function UsersPage({ }) {
|
||||
setUsers(response.data)
|
||||
}).catch(
|
||||
(error) => {
|
||||
console.log('Failed to get servers: ' + error);
|
||||
console.log('Failed to get users: ' + error);
|
||||
if (error.response) {
|
||||
if (error.response.status === 401) {
|
||||
setApiAuthenticated(false)
|
||||
|
Loading…
x
Reference in New Issue
Block a user