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"
|
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: {
|
PasswordRequestForm: {
|
||||||
properties: {
|
properties: {
|
||||||
username: {
|
username: {
|
||||||
@ -345,54 +324,6 @@ const definitions = {
|
|||||||
],
|
],
|
||||||
title: "SetServerNicknameRequest"
|
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: {
|
Token: {
|
||||||
properties: {
|
properties: {
|
||||||
access_token: {
|
access_token: {
|
||||||
@ -482,7 +413,29 @@ export const SERVER_ACTIONS: ActionInfo[] = [
|
|||||||
{
|
{
|
||||||
name: "Start",
|
name: "Start",
|
||||||
args: {
|
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,
|
definitions: definitions,
|
||||||
},
|
},
|
||||||
requestType: "post",
|
requestType: "post",
|
||||||
@ -554,27 +507,66 @@ export const SERVER_ACTIONS: ActionInfo[] = [
|
|||||||
response_action: "Browse"
|
response_action: "Browse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Set Nickname",
|
name: "Update Server",
|
||||||
|
requestType: "patch",
|
||||||
|
endpoint: "/servers/{server_id}",
|
||||||
|
permissions: Permission.Admin,
|
||||||
|
response_action: "Ignore",
|
||||||
args: {
|
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,
|
definitions: definitions,
|
||||||
|
|
||||||
},
|
},
|
||||||
requestType: "post",
|
|
||||||
endpoint: "/servers/{server_id}/nickname",
|
|
||||||
permissions: Permission.Admin,
|
|
||||||
response_action: "Ignore"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Add Permissions",
|
name: "Add Permissions",
|
||||||
args: {
|
|
||||||
"$ref": "#/definitions/SetServerPermissionsRequest",
|
|
||||||
definitions: definitions,
|
|
||||||
},
|
|
||||||
requestType: "post",
|
requestType: "post",
|
||||||
endpoint: "/servers/{server_id}/permissions",
|
endpoint: "/servers/{server_id}/permissions",
|
||||||
permissions: Permission.Admin,
|
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 = {
|
export const INVITE_USER_ACTION: ActionInfo = {
|
||||||
name: "Invite User",
|
name: "Invite User",
|
||||||
args: {
|
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,
|
definitions: definitions,
|
||||||
},
|
},
|
||||||
requestType: "post",
|
requestType: "post",
|
||||||
|
@ -6,8 +6,7 @@ import { Box, Button, ButtonGroup, ButtonOwnProps, Modal, PaletteMode, Paper, Ta
|
|||||||
import { Form } from "@rjsf/mui";
|
import { Form } from "@rjsf/mui";
|
||||||
import validator from '@rjsf/validator-ajv8';
|
import validator from '@rjsf/validator-ajv8';
|
||||||
import { blue, grey } from "@mui/material/colors";
|
import { blue, grey } from "@mui/material/colors";
|
||||||
import { OpenAPISchema, User } from "./interfaces";
|
import { User } from "./interfaces";
|
||||||
import { JSONSchema7 } from "json-schema";
|
|
||||||
import { IChangeEvent } from "@rjsf/core";
|
import { IChangeEvent } from "@rjsf/core";
|
||||||
import { RJSFSchema, WidgetProps } from "@rjsf/utils";
|
import { RJSFSchema, WidgetProps } from "@rjsf/utils";
|
||||||
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
||||||
@ -99,7 +98,7 @@ export function ApiWrapper(p: { children: ReactNode}) {
|
|||||||
|
|
||||||
export interface ActionInfo {
|
export interface ActionInfo {
|
||||||
name: string
|
name: string
|
||||||
requestType: 'post' | 'get' | 'delete'
|
requestType: 'post' | 'get' | 'delete' | 'patch'
|
||||||
endpoint: string
|
endpoint: string
|
||||||
args: {}
|
args: {}
|
||||||
permissions?: number
|
permissions?: number
|
||||||
@ -114,16 +113,63 @@ interface Options{
|
|||||||
|
|
||||||
export const actionIdentifierContext: Context<string> = createContext('')
|
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 jp = require('jsonpath')
|
||||||
const [options2, setOptions]: [Options[]|null, Dispatch<Options[]>] = useState(null as Options[]|null)
|
const [options2, setOptions]: [Options[]|null, Dispatch<Options[]>] = useState(null as Options[]|null)
|
||||||
const {schema, registry, options, ...newProps} = props
|
const {schema, registry, options, ...newProps} = props
|
||||||
const {SelectWidget} = registry.widgets
|
const {SelectWidget, CheckboxesWidget} = registry.widgets
|
||||||
|
|
||||||
if (!schema.fetch_url){
|
if (!schema.fetch_url){
|
||||||
|
if (!schema.permissions){
|
||||||
return <TextField onChange={(event)=>(props.onChange(event.target.value))} value={props.value} label={props.label}/>
|
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){
|
if (options2 === null){
|
||||||
api.get(schema.fetch_url as string).then((event)=>{
|
api.get(schema.fetch_url as string).then((event)=>{
|
||||||
let newOptions: Options[] = []
|
let newOptions: Options[] = []
|
||||||
@ -142,7 +188,6 @@ function FetcherField(props: WidgetProps){
|
|||||||
|
|
||||||
|
|
||||||
function isUserAllowed(user: User|null, action: ActionInfo): boolean{
|
function isUserAllowed(user: User|null, action: ActionInfo): boolean{
|
||||||
console.log({User: user, Action: action})
|
|
||||||
if (user === null){
|
if (user === null){
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -171,6 +216,7 @@ export function ActionItem(p: { action: ActionInfo, identifierSubstring?: string
|
|||||||
|
|
||||||
const [form, setForm] = useState(false);
|
const [form, setForm] = useState(false);
|
||||||
const [formData, setFormData]: [RJSFSchema, Dispatch<RJSFSchema>] = useState({})
|
const [formData, setFormData]: [RJSFSchema, Dispatch<RJSFSchema>] = useState({})
|
||||||
|
console.log(formData)
|
||||||
|
|
||||||
|
|
||||||
function handleSubmit() {
|
function handleSubmit() {
|
||||||
@ -181,6 +227,10 @@ export function ActionItem(p: { action: ActionInfo, identifierSubstring?: string
|
|||||||
promise = api.post(url, formData)
|
promise = api.post(url, formData)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case 'patch':{
|
||||||
|
promise = api.patch(url, formData)
|
||||||
|
break
|
||||||
|
}
|
||||||
case 'get': {
|
case 'get': {
|
||||||
if (formData){
|
if (formData){
|
||||||
console.warn('get can get no arguments, dropping')
|
console.warn('get can get no arguments, dropping')
|
||||||
@ -218,7 +268,7 @@ export function ActionItem(p: { action: ActionInfo, identifierSubstring?: string
|
|||||||
open={form}
|
open={form}
|
||||||
>
|
>
|
||||||
<Box sx={formModalStyle}>
|
<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>
|
</Box>
|
||||||
</Modal>
|
</Modal>
|
||||||
</>)
|
</>)
|
||||||
@ -294,9 +344,6 @@ export function ActionGroup(p: { actions: ActionInfo[], identifierSubstring?: st
|
|||||||
<ClickAwayListener onClickAway={handleClose}>
|
<ClickAwayListener onClickAway={handleClose}>
|
||||||
<MenuList id="split-button-menu" autoFocusItem>
|
<MenuList id="split-button-menu" autoFocusItem>
|
||||||
{actionItems.map((option, index) => {
|
{actionItems.map((option, index) => {
|
||||||
if (!option.props){
|
|
||||||
console.log(actionItems)
|
|
||||||
}
|
|
||||||
return <MenuItem
|
return <MenuItem
|
||||||
key={option.props.action.name}
|
key={option.props.action.name}
|
||||||
selected={index === selectedIndex}
|
selected={index === selectedIndex}
|
||||||
|
@ -48,7 +48,6 @@ function UserItem(p: { user: User }) {
|
|||||||
export function UsersPage({ }) {
|
export function UsersPage({ }) {
|
||||||
const [apiAuthenticated, setApiAuthenticated] = useContext(apiAuthenticatedContext)
|
const [apiAuthenticated, setApiAuthenticated] = useContext(apiAuthenticatedContext)
|
||||||
const [users, setUsers]: [User[], Dispatch<User[]>] = useState([] as User[])
|
const [users, setUsers]: [User[], Dispatch<User[]>] = useState([] as User[])
|
||||||
console.log({apiAuthenticated: apiAuthenticated, users: users})
|
|
||||||
|
|
||||||
const action: ActionInfo|undefined = INVITE_USER_ACTION
|
const action: ActionInfo|undefined = INVITE_USER_ACTION
|
||||||
|
|
||||||
@ -60,7 +59,7 @@ export function UsersPage({ }) {
|
|||||||
setUsers(response.data)
|
setUsers(response.data)
|
||||||
}).catch(
|
}).catch(
|
||||||
(error) => {
|
(error) => {
|
||||||
console.log('Failed to get servers: ' + error);
|
console.log('Failed to get users: ' + error);
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
if (error.response.status === 401) {
|
if (error.response.status === 401) {
|
||||||
setApiAuthenticated(false)
|
setApiAuthenticated(false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user