1 Commits

Author SHA1 Message Date
2e71eec32b Update Rust crate thiserror to v2.0.11
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-01-11 00:24:58 +00:00
20 changed files with 1884 additions and 3266 deletions

View File

@ -1,11 +1,4 @@
# VirtWeb Remote # VirtWeb Remote
Web UI that allows to start and stop VMs managed by VirtWEB without having to expose the VirtWEB directly on the Internet. WIP project
VirtWebRemote rely on OpenID to authenticate users. This project aims to use the VirtWeb API to start and stop VM without directly exposing the VirtWEB API to the Internet.
VirtWebRemote authenticates against VirtWEB API using an API token. Both the token ID and private key are required to be able to authenticate against the VirtWEB API.
## Docker image options
```bash
docker run --rm -it pierre42100/virtweb_remote --help
```

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,28 @@
[package] [package]
name = "remote_backend" name = "remote_backend"
version = "0.1.0" version = "0.1.0"
edition = "2024" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "0.4.27" log = "0.4.21"
env_logger = "0.11.8" env_logger = "0.11.3"
clap = { version = "4.5.40", features = ["derive", "env"] } clap = { version = "4.5.21", features = ["derive", "env"] }
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.215", features = ["derive"] }
light-openid = { version = "1.0.4", features = ["crypto-wrapper"] } light-openid = { version = "1.0.2", features = ["crypto-wrapper"] }
basic-jwt = "0.3.0" basic-jwt = "0.2.0"
actix-web = "4.10.2" actix-web = "4.5.1"
actix-remote-ip = "0.1.0" actix-remote-ip = "0.1.0"
actix-session = { version = "0.10.1", features = ["cookie-session"] } actix-session = { version = "0.10.1", features = ["cookie-session"] }
actix-identity = "0.8.0" actix-identity = "0.8.0"
actix-cors = "0.7.1" actix-cors = "0.7.0"
lazy_static = "1.5.0" lazy_static = "1.4.0"
anyhow = "1.0.98" anyhow = "1.0.93"
reqwest = { version = "0.12.20", features = ["json"] } reqwest = { version = "0.12.9", features = ["json"] }
thiserror = "2.0.12" thiserror = "2.0.3"
uuid = { version = "1.16.0", features = ["v4", "serde"] } uuid = { version = "1.8.0", features = ["v4", "serde"] }
futures-util = "0.3.31" futures-util = "0.3.30"
lazy-regex = "3.4.1" lazy-regex = "3.1.0"
mime_guess = "2.0.5" mime_guess = "2.0.4"
rust-embed = { version = "8.7.2" } rust-embed = { version = "8.3.0" }

View File

@ -1,6 +1,6 @@
use actix_remote_ip::RemoteIP; use actix_remote_ip::RemoteIP;
use actix_web::web::Data; use actix_web::web::Data;
use actix_web::{HttpResponse, Responder, web}; use actix_web::{web, HttpResponse, Responder};
use light_openid::basic_state_manager::BasicStateManager; use light_openid::basic_state_manager::BasicStateManager;
use crate::app_config::AppConfig; use crate::app_config::AppConfig;

View File

@ -1,7 +1,7 @@
use crate::controllers::HttpResult; use crate::controllers::HttpResult;
use crate::virtweb_client; use crate::virtweb_client;
use crate::virtweb_client::{GroupID, VMUuid}; use crate::virtweb_client::{GroupID, VMUuid};
use actix_web::{HttpResponse, web}; use actix_web::{web, HttpResponse};
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
pub struct GroupIDInPath { pub struct GroupIDInPath {

View File

@ -1,8 +1,9 @@
use actix_web::HttpResponse;
use actix_web::body::BoxBody; use actix_web::body::BoxBody;
use actix_web::http::StatusCode; use actix_web::http::StatusCode;
use actix_web::HttpResponse;
use std::error::Error; use std::error::Error;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::io::ErrorKind;
pub mod auth_controller; pub mod auth_controller;
pub mod group_controller; pub mod group_controller;
@ -51,7 +52,7 @@ impl From<anyhow::Error> for HttpErr {
impl From<Box<dyn Error>> for HttpErr { impl From<Box<dyn Error>> for HttpErr {
fn from(value: Box<dyn Error>) -> Self { fn from(value: Box<dyn Error>) -> Self {
HttpErr::Err(std::io::Error::other(value.to_string()).into()) HttpErr::Err(std::io::Error::new(ErrorKind::Other, value.to_string()).into())
} }
} }
@ -81,7 +82,7 @@ impl From<reqwest::header::ToStrError> for HttpErr {
impl From<actix_web::Error> for HttpErr { impl From<actix_web::Error> for HttpErr {
fn from(value: actix_web::Error) -> Self { fn from(value: actix_web::Error) -> Self {
HttpErr::Err(std::io::Error::other(value.to_string()).into()) HttpErr::Err(std::io::Error::new(ErrorKind::Other, value.to_string()).into())
} }
} }

View File

@ -18,7 +18,7 @@ mod serve_static_debug {
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
mod serve_static_release { mod serve_static_release {
use actix_web::{HttpResponse, Responder, web}; use actix_web::{web, HttpResponse, Responder};
use rust_embed::RustEmbed; use rust_embed::RustEmbed;
#[derive(RustEmbed)] #[derive(RustEmbed)]

View File

@ -3,7 +3,7 @@
use crate::controllers::HttpResult; use crate::controllers::HttpResult;
use crate::virtweb_client; use crate::virtweb_client;
use crate::virtweb_client::VMUuid; use crate::virtweb_client::VMUuid;
use actix_web::{HttpResponse, web}; use actix_web::{web, HttpResponse};
#[derive(serde::Deserialize)] #[derive(serde::Deserialize)]
pub struct ReqPath { pub struct ReqPath {

View File

@ -1,7 +1,7 @@
use actix_identity::Identity; use actix_identity::Identity;
use actix_web::dev::Payload; use actix_web::dev::Payload;
use actix_web::{Error, FromRequest, HttpMessage, HttpRequest}; use actix_web::{Error, FromRequest, HttpMessage, HttpRequest};
use futures_util::future::{Ready, ready}; use futures_util::future::{ready, Ready};
use std::fmt::Display; use std::fmt::Display;
pub struct AuthExtractor { pub struct AuthExtractor {

View File

@ -1,13 +1,13 @@
use actix_cors::Cors; use actix_cors::Cors;
use actix_identity::IdentityMiddleware;
use actix_identity::config::LogoutBehaviour; use actix_identity::config::LogoutBehaviour;
use actix_identity::IdentityMiddleware;
use actix_remote_ip::RemoteIPConfig; use actix_remote_ip::RemoteIPConfig;
use actix_session::SessionMiddleware;
use actix_session::storage::CookieSessionStore; use actix_session::storage::CookieSessionStore;
use actix_session::SessionMiddleware;
use actix_web::cookie::{Key, SameSite}; use actix_web::cookie::{Key, SameSite};
use actix_web::middleware::Logger; use actix_web::middleware::Logger;
use actix_web::web::Data; use actix_web::web::Data;
use actix_web::{App, HttpServer, web}; use actix_web::{web, App, HttpServer};
use light_openid::basic_state_manager::BasicStateManager; use light_openid::basic_state_manager::BasicStateManager;
use remote_backend::app_config::AppConfig; use remote_backend::app_config::AppConfig;
use remote_backend::constants; use remote_backend::constants;

View File

@ -1,4 +1,4 @@
use std::future::{Ready, ready}; use std::future::{ready, Ready};
use std::rc::Rc; use std::rc::Rc;
use crate::app_config::AppConfig; use crate::app_config::AppConfig;
@ -7,8 +7,8 @@ use crate::extractors::auth_extractor::AuthExtractor;
use actix_web::body::EitherBody; use actix_web::body::EitherBody;
use actix_web::dev::Payload; use actix_web::dev::Payload;
use actix_web::{ use actix_web::{
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
Error, FromRequest, HttpResponse, Error, FromRequest, HttpResponse,
dev::{Service, ServiceRequest, ServiceResponse, Transform, forward_ready},
}; };
use futures_util::future::LocalBoxFuture; use futures_util::future::LocalBoxFuture;

View File

@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}

View File

@ -1,28 +0,0 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
)

File diff suppressed because it is too large Load Diff

View File

@ -10,25 +10,22 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@fluentui/react-components": "^9.66.2", "@fluentui/react-components": "^9.56.3",
"@fluentui/react-icons": "^2.0.304", "@fluentui/react-icons": "^2.0.266",
"filesize": "^10.1.6", "filesize": "^10.1.6",
"react": "^18.3.1", "react": "^18.2.0",
"react-dom": "^18.3.1" "react-dom": "^18.2.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.29.0", "@types/react": "^18.3.12",
"@types/react": "^18.3.23", "@types/react-dom": "^18.3.1",
"@types/react-dom": "^18.3.7", "@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/eslint-plugin": "^8.34.1", "@typescript-eslint/parser": "^8.16.0",
"@typescript-eslint/parser": "^8.34.1", "@vitejs/plugin-react": "^4.3.4",
"@vitejs/plugin-react": "^4.4.1", "eslint": "^9.0.0",
"eslint": "^9.26.0", "eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.14",
"eslint-plugin-react-refresh": "^0.4.20", "typescript": "^5.7.2",
"globals": "^16.1.0", "vite": "^6.0.1"
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.1",
"vite": "^6.3.5"
} }
} }

View File

@ -1,26 +0,0 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}

View File

@ -1,7 +1,25 @@
{ {
"files": [], "compilerOptions": {
"references": [ "target": "ES2020",
{ "path": "./tsconfig.app.json" }, "useDefineForClassFields": true,
{ "path": "./tsconfig.node.json" } "lib": ["ES2020", "DOM", "DOM.Iterable"],
] "module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
} }

View File

@ -1,24 +1,11 @@
{ {
"compilerOptions": { "compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "composite": true,
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true, "skipLibCheck": true,
"module": "ESNext",
/* Bundler mode */
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowSyntheticDefaultImports": true,
"isolatedModules": true, "strict": true
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
}, },
"include": ["vite.config.ts"] "include": ["vite.config.ts"]
} }

View File

@ -1,7 +1,7 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react'
// https://vite.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
}) })

View File

@ -1,3 +1,9 @@
{ {
"extends": ["local>renovate/presets"] "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"packageRules": [
{
"matchUpdateTypes": ["major", "minor", "patch"],
"automerge": true
}
]
} }