added go stuff

This commit is contained in:
ACoolName 2024-05-21 19:41:04 +03:00
parent b8cebf8c5c
commit 871f61e910
8 changed files with 11163 additions and 10563 deletions

20978
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
{ {
"name": "a-cool-games-manager", name: "a-cool-games-manager",
"version": "0.1.0", version: "0.1.0",
"private": true, private: true,
"dependencies": { dependencies: {
"@rjsf/core": "^5.14.2", "@rjsf/core": "^5.14.2",
"@rjsf/mui": "^5.14.2", "@rjsf/mui": "^5.14.2",
"@rjsf/utils": "^5.14.2", "@rjsf/utils": "^5.14.2",
@ -16,39 +16,39 @@
"@types/react": "^18.2.38", "@types/react": "^18.2.38",
"@types/react-dom": "^18.2.16", "@types/react-dom": "^18.2.16",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"axios": "^1.6.2", axios: "^1.6.2",
"dotenv": "^16.3.1", dotenv: "^16.3.1",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"jsonpath": "^1.1.1", jsonpath: "^1.1.1",
"react": "^18.2.0", react: "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-jsonschema-form": "^1.8.1", "react-jsonschema-form": "^1.8.1",
"react-router-dom": "^6.19.0", "react-router-dom": "^6.19.0",
"react-routes": "^0.2.6", "react-routes": "^0.2.6",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"serve": "^14.2.1", serve: "^14.2.1",
"typescript": "^4.9.5", typescript: "^4.9.5",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { scripts: {
"start": "react-scripts start", start: "react-scripts start",
"build": "/usr/bin/env react-scripts build", build: "/usr/bin/env react-scripts build",
"test": "react-scripts test", test: "react-scripts test",
"eject": "react-scripts eject" eject: "react-scripts eject"
}, },
"eslintConfig": { eslintConfig: {
"extends": [ extends: [
"react-app", "react-app",
"react-app/jest" "react-app/jest"
] ]
}, },
"browserslist": { browserslist: {
"production": [ production: [
">0.2%", ">0.2%",
"not dead", "not dead",
"not op_mini all" "not op_mini all"
], ],
"development": [ development: [
"last 1 chrome version", "last 1 chrome version",
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"

View File

@ -1,25 +1,25 @@
{ {
"short_name": "React App", short_name: "React App",
"name": "Create React App Sample", name: "Create React App Sample",
"icons": [ icons: [
{ {
"src": "favicon.ico", src: "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16", sizes: "64x64 32x32 24x24 16x16",
"type": "image/x-icon" type: "image/x-icon"
}, },
{ {
"src": "logo192.png", src: "logo192.png",
"type": "image/png", type: "image/png",
"sizes": "192x192" sizes: "192x192"
}, },
{ {
"src": "logo512.png", src: "logo512.png",
"type": "image/png", type: "image/png",
"sizes": "512x512" sizes: "512x512"
} }
], ],
"start_url": ".", start_url: ".",
"display": "standalone", display: "standalone",
"theme_color": "#000000", theme_color: "#000000",
"background_color": "#ffffff" background_color: "#ffffff"
} }

598
src/actions.tsx Normal file
View File

@ -0,0 +1,598 @@
import { ActionInfo } from "./common"
export const Permission = {
Start: 1,
Stop: 1 << 2,
Browse: 1 << 3,
Create: 1 << 4,
Delete: 1 << 5,
RunCommand: 1 << 6,
Admin: 1 << 7,
}
const definitions = {
ChangeUserRequest: {
properties: {
permissions: {
items: {
"$ref": "#/definitions/Permission"
},
type: "array",
title: "Permissions"
}
},
type: "object",
required: [
"permissions"
],
title: "ChangeUserRequest"
},
CreateServer: {
properties: {
image_id: {
type: "string",
title: "Image Id",
fetch_display_path: "display_name",
fetch_key_path: "id_",
fetch_url: "/images"
}
},
type: "object",
required: [
"image_id"
],
title: "CreateServer"
},
CreateUserRequest: {
properties: {
username: {
type: "string",
title: "Username"
},
password: {
type: "string",
title: "Password"
}
},
type: "object",
required: [
"username",
"password"
],
title: "CreateUserRequest"
},
FileBrowserInfo: {
properties: {
id_: {
type: "string",
title: "Id "
},
owner_id: {
type: "string",
title: "Owner Id"
},
domain: {
type: "string",
title: "Domain"
},
connected_to: {
"$ref": "#/definitions/ServerInfo"
},
url: {
type: "string",
title: "Url",
readOnly: true
}
},
type: "object",
required: [
"id_",
"owner_id",
"domain",
"connected_to",
"url"
],
title: "FileBrowserInfo"
},
HTTPValidationError: {
properties: {
detail: {
items: {
"$ref": "#/definitions/ValidationError"
},
type: "array",
title: "Detail"
}
},
type: "object",
title: "HTTPValidationError"
},
ImageInfo: {
properties: {
name: {
type: "string",
title: "Name"
},
version: {
type: "string",
title: "Version"
},
ports: {
items: {
"$ref": "#/definitions/Port-Output"
},
type: "array",
uniqueItems: true,
title: "Ports"
},
id_: {
type: "string",
title: "Id ",
readOnly: true
},
display_name: {
type: "string",
title: "Display Name",
readOnly: true
}
},
type: "object",
required: [
"name",
"version",
"id_",
"display_name"
],
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: {
type: "string",
title: "Username"
},
password: {
type: "string",
title: "Password"
},
remember: {
anyOf: [
{
type: "boolean"
},
{
type: "string"
}
],
title: "Remember",
default: false
}
},
type: "object",
required: [
"username",
"password"
],
title: "PasswordRequestForm"
},
Permission: {
type: "number",
enum: [
"create",
"start",
"browse",
"cloud",
"run-command",
"delete",
"stop",
"admin"
],
title: "Permission"
},
"Port-Input": {
properties: {
number: {
type: "integer",
exclusiveMaximum: 65535,
exclusiveMinimum: 1,
title: "Number"
},
protocol: {
"$ref": "#/definitions/PortProtocol"
}
},
type: "object",
required: [
"number",
"protocol"
],
title: "Port"
},
"Port-Output": {
properties: {
number: {
type: "integer",
exclusiveMaximum: 65535,
exclusiveMinimum: 1,
title: "Number"
},
protocol: {
"$ref": "#/definitions/PortProtocol"
},
id_: {
type: "string",
title: "Id ",
readOnly: true
}
},
type: "object",
required: [
"number",
"protocol",
"id_"
],
title: "Port"
},
PortMapping: {
properties: {
source_port: {
"$ref": "#/definitions/Port-Input"
},
destination_port: {
anyOf: [
{
"$ref": "#/definitions/Port-Input"
},
{
type: "null"
}
]
}
},
type: "object",
required: [
"source_port"
],
title: "PortMapping"
},
PortProtocol: {
type: "string",
enum: [
"tcp",
"udp"
],
title: "PortProtocol"
},
RunCommandRequest: {
properties: {
command: {
type: "string",
title: "Command"
}
},
type: "object",
required: [
"command"
],
title: "RunCommandRequest"
},
ServerInfo: {
properties: {
id_: {
type: "string",
title: "Id "
},
user_id: {
type: "string",
title: "User Id"
},
image: {
"$ref": "#/definitions/ImageInfo"
},
on: {
type: "boolean",
title: "On"
},
domain: {
anyOf: [
{
type: "string"
},
{
type: "null"
}
],
title: "Domain"
},
ports: {
anyOf: [
{
items: {
"$ref": "#/definitions/Port-Output"
},
type: "array",
uniqueItems: true
},
{
type: "null"
}
],
title: "Ports"
},
nickname: {
anyOf: [
{
type: "string"
},
{
type: "null"
}
],
title: "Nickname"
}
},
type: "object",
required: [
"id_",
"user_id",
"image",
"on"
],
title: "ServerInfo"
},
SetServerNicknameRequest: {
properties: {
nickname: {
type: "string",
title: "Nickname"
}
},
type: "object",
required: [
"nickname"
],
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: {
type: "string",
title: "Access Token"
},
token_type: {
type: "string",
title: "Token Type"
}
},
type: "object",
required: [
"access_token",
"token_type"
],
title: "Token"
},
UserView: {
properties: {
username: {
type: "string",
title: "Username"
},
email: {
type: "string",
title: "Email"
},
max_owned_servers: {
type: "integer",
title: "Max Owned Servers",
default: 5
},
permissions: {
items: {
"$ref": "#/definitions/Permission"
},
type: "array",
title: "Permissions"
}
},
type: "object",
required: [
"username",
"email"
],
title: "UserView"
},
ValidationError: {
properties: {
loc: {
items: {
anyOf: [
{
type: "string"
},
{
type: "integer"
}
]
},
type: "array",
title: "Location"
},
msg: {
type: "string",
title: "Message"
},
type: {
type: "string",
title: "Error Type"
}
},
type: "object",
required: [
"loc",
"msg",
"type"
],
title: "ValidationError"
}
}
export const SERVER_ACTIONS: ActionInfo[] = [
{
name: "Start",
args: {
"$ref": "#/definitions/StartServerRequest",
definitions: definitions,
},
requestType: "post",
endpoint: "/servers/{server_id}/start",
permissions: Permission.Start,
response_action: "Ignore"
},
{
name: "Stop",
args: {
title: "Stop",
type: "object",
required: [],
properties: {},
default: {}
},
requestType: "post",
endpoint: "/servers/{server_id}/stop",
permissions: Permission.Stop,
response_action: "Ignore"
},
{
name: "Delete Server",
args: {
title: "Delete Server",
type: "object",
required: [],
properties: {},
default: {}
},
requestType: "delete",
endpoint: "/servers/{server_id}",
permissions: Permission.Delete,
response_action: "Ignore"
},
{
name: "Run Command",
args: {
"$ref": "#/definitions/RunCommandRequest",
definitions: definitions,
},
requestType: "post",
endpoint: "/servers/{server_id}/command",
permissions: Permission.RunCommand,
response_action: "Ignore"
},
{
name: "Browse",
args: {
title: "Browse",
type: "object",
required: [],
properties: {},
default: {}
},
requestType: "post",
endpoint: "/servers/{server_id}/browse",
permissions: Permission.Browse,
response_action: "Browse"
},
{
name: "Set Nickname",
args: {
"$ref": "#/definitions/SetServerNicknameRequest",
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"
}
]

View File

@ -16,6 +16,7 @@ import Grow from '@mui/material/Grow';
import Popper from '@mui/material/Popper'; import Popper from '@mui/material/Popper';
import MenuItem from '@mui/material/MenuItem'; import MenuItem from '@mui/material/MenuItem';
import MenuList from '@mui/material/MenuList'; import MenuList from '@mui/material/MenuList';
import { Permission } from "./actions";
export const apiAuthenticatedContext: Context<[boolean, Dispatch<boolean>]> = createContext([false, (value: boolean) => {}] as [boolean, Dispatch<boolean>]) export const apiAuthenticatedContext: Context<[boolean, Dispatch<boolean>]> = createContext([false, (value: boolean) => {}] as [boolean, Dispatch<boolean>])
@ -131,15 +132,15 @@ export interface ActionInfo {
requestType: 'post' | 'get' | 'delete' requestType: 'post' | 'get' | 'delete'
endpoint: string endpoint: string
args: {} args: {}
permissions?: string[] permissions?: number
response_action?: 'Ignore' | 'Browse' response_action?: 'Ignore' | 'Browse' | 'Terminal'
} }
export function useActions(api: AxiosInstance, path_prefix: string): ActionInfo[] { export function useActions(api: AxiosInstance, path_prefix: string): ActionInfo[] {
const openapi: OpenAPISchema|null = useContext(OpenApiContext) const openapi: OpenAPISchema|null = useContext(OpenApiContext)
let [actions, setActions]: [Record<string, ActionInfo[]>, Dispatch<Record<string, ActionInfo[]>>] = useState({}) let [actions, setActions]: [Record<string, ActionInfo[]>, Dispatch<Record<string, ActionInfo[]>>] = useState({})
console.log(actions)
if (actions[path_prefix] && actions[path_prefix].length > 0) { if (actions[path_prefix] && actions[path_prefix].length > 0) {
return actions[path_prefix] return actions[path_prefix]
} }
@ -160,7 +161,7 @@ export function useActions(api: AxiosInstance, path_prefix: string): ActionInfo[
responseActions.push( responseActions.push(
{ {
name: schema.summary, name: schema.summary,
args: JSON.parse(JSON.stringify(formSchema).replaceAll('#/components', '#/definitions')), args: formSchema,
requestType: (method as 'get' | 'post' | 'delete'), requestType: (method as 'get' | 'post' | 'delete'),
endpoint: path, endpoint: path,
permissions: schema.permissions, permissions: schema.permissions,
@ -256,7 +257,7 @@ function isUserAllowed(user: User|null, action: ActionInfo): boolean{
return false return false
} }
const isAdmin = user.permissions.includes('admin') const isAdmin = (user.permissions & Permission.Admin) === Permission.Admin
if (isAdmin){ if (isAdmin){
return true return true
} }
@ -265,7 +266,7 @@ function isUserAllowed(user: User|null, action: ActionInfo): boolean{
return true return true
} }
if (action.permissions.every((v)=>(user.permissions.includes(v)))){ if ((action.permissions & user.permissions) == action.permissions){
return true return true
} }

View File

@ -29,7 +29,7 @@ export interface ServerInfo {
export interface User { export interface User {
username: string username: string
email: string email: string
permissions: string[] permissions: number
} }
@ -46,7 +46,7 @@ export interface OpenApiMethodSchema {
summary: string summary: string
requestBody: {content: Record<string, {schema: JSONSchema7}>} requestBody: {content: Record<string, {schema: JSONSchema7}>}
api_response: 'Ignore' | 'Browse' api_response: 'Ignore' | 'Browse'
permissions: string[] permissions: number
} }

View File

@ -4,6 +4,7 @@ import React, { Context, Dispatch, createContext, useContext, useEffect, useStat
import { TableRow, TableCell, Chip } from "@mui/material" import { TableRow, TableCell, Chip } from "@mui/material"
import { ImageInfo, ServerInfo } from "./interfaces" import { ImageInfo, ServerInfo } from "./interfaces"
import { JSONSchema7 } from "json-schema" import { JSONSchema7 } from "json-schema"
import { Permission } from "./actions"
@ -20,20 +21,20 @@ const serverActionsContext: Context<ActionInfo[]> = createContext([] as ActionIn
function ServerItem(props: { server_info: ServerInfo }) { function ServerItem(props: { server_info: ServerInfo }) {
const actions = useContext(serverActionsContext) const actions = useContext(serverActionsContext)
const [serverPermissions, setServerPermissions] = useState(null as null|string[]) const [serverPermissions, setServerPermissions] = useState(null as null|number)
const user = useContext(UserInfoContext) const user = useContext(UserInfoContext)
let permissions: string[] = [] let permissions = 0
if (props.server_info.user_id === user?.username){ if (props.server_info.user_id === user?.username){
permissions.push('admin') permissions |= Permission.Admin
}else{ }else{
if (serverPermissions === null){ if (serverPermissions === null){
api.get(`/servers/${props.server_info.id_}/permissions`).then((event)=>{setServerPermissions(event.data)}) api.get(`/servers/${props.server_info.id_}/permissions`).then((event)=>{setServerPermissions(event.data)})
}else{ }else{
permissions.push(...serverPermissions) permissions |= serverPermissions
} }
if (user){ if (user){
permissions.push(...user.permissions) permissions |= user.permissions
} }
} }
@ -70,18 +71,18 @@ export default function ServersBoard() {
const [images, setImages] = useState([] as ImageInfo[]) const [images, setImages] = useState([] as ImageInfo[])
let schema: JSONSchema7 = { let schema: JSONSchema7 = {
"properties": { properties: {
"image_id": { image_id: {
"type": "string", type: "string",
"oneOf": images.map((value, index, array) => { return { "const": value.id_, "title": `${value.name} ${value.version}` } }), oneOf: images.map((value, index, array) => { return { const: value.id_, title: `${value.name} ${value.version}` } }),
"title": "Image Id" title: "Image Id"
} }
}, },
"type": "object", type: "object",
"required": [ required: [
"image_id" "image_id"
], ],
"title": "CreateServer" title: "CreateServer"
} }

View File

@ -1,26 +1,26 @@
{ {
"compilerOptions": { compilerOptions: {
"target": "es5", target: "es5",
"lib": [ lib: [
"dom", "dom",
"dom.iterable", "dom.iterable",
"esnext" "esnext"
], ],
"allowJs": true, allowJs: true,
"skipLibCheck": true, skipLibCheck: true,
"esModuleInterop": true, esModuleInterop: true,
"allowSyntheticDefaultImports": true, allowSyntheticDefaultImports: true,
"strict": true, strict: true,
"forceConsistentCasingInFileNames": true, forceConsistentCasingInFileNames: true,
"noFallthroughCasesInSwitch": true, noFallthroughCasesInSwitch: true,
"module": "esnext", module: "esnext",
"moduleResolution": "node", moduleResolution: "node",
"resolveJsonModule": true, resolveJsonModule: true,
"isolatedModules": true, isolatedModules: true,
"noEmit": true, noEmit: true,
"jsx": "react-jsx" jsx: "react-jsx"
}, },
"include": [ include: [
"src" "src"
] ]
} }