parent
643a5755c0
commit
df361947cd
@ -162,6 +162,10 @@ impl DBConnection {
|
|||||||
|
|
||||||
pub fn save_node(&mut self, span: &Span, node: &super::Inode) { DB_MANAGER.save_node(span, &mut self.db, node); }
|
pub fn save_node(&mut self, span: &Span, node: &super::Inode) { DB_MANAGER.save_node(span, &mut self.db, node); }
|
||||||
|
|
||||||
|
pub fn move_node(&mut self, span: &Span, node: &mut super::Inode, target: i32) {
|
||||||
|
DB_MANAGER.move_node(span, &mut self.db, node, target);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn delete_node(&mut self, span: &Span, node: &super::Inode) {
|
pub fn delete_node(&mut self, span: &Span, node: &super::Inode) {
|
||||||
DB_MANAGER.delete_node(span, &mut self.db, node);
|
DB_MANAGER.delete_node(span, &mut self.db, node);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,12 @@ impl DBManager {
|
|||||||
diesel::update(node).set(node.clone()).execute(db).expect("Failed to save node");
|
diesel::update(node).set(node.clone()).execute(db).expect("Failed to save node");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_node(&self, span: &Span, db: &mut super::RawDBConnection, node: &mut Inode, target: i32) {
|
||||||
|
self.children_cache.remove(&node.parent_id.unwrap_or(0));
|
||||||
|
node.parent_id = Some(target);
|
||||||
|
self.save_node(span, db, node);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn delete_node(&self, span: &Span, db: &mut super::RawDBConnection, node: &Inode) {
|
pub fn delete_node(&self, span: &Span, db: &mut super::RawDBConnection, node: &Inode) {
|
||||||
let inner_span = metrics::span("delete_node", span);
|
let inner_span = metrics::span("delete_node", span);
|
||||||
let owner = node.owner_id.to_string();
|
let owner = node.owner_id.to_string();
|
||||||
|
@ -186,6 +186,12 @@ pub mod requests {
|
|||||||
pub name: String
|
pub name: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct MoveNode {
|
||||||
|
pub nodes: Vec<i32>,
|
||||||
|
pub target: i32
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct CreateZip {
|
pub struct CreateZip {
|
||||||
pub nodes: Vec<i32>
|
pub nodes: Vec<i32>
|
||||||
|
@ -77,16 +77,18 @@ fn handle_request(mut req: Request, db: db::DBPool) {
|
|||||||
AppError::NotFound => 404,
|
AppError::NotFound => 404,
|
||||||
AppError::InternalError(_) => 500
|
AppError::InternalError(_) => 500
|
||||||
};
|
};
|
||||||
Response::from_data(
|
let msg = match v {
|
||||||
serde_json::to_vec(&dto::responses::Error {
|
|
||||||
statusCode: code,
|
|
||||||
message: match v {
|
|
||||||
AppError::BadRequest(v) => v.to_string(),
|
AppError::BadRequest(v) => v.to_string(),
|
||||||
AppError::Unauthorized(v) => v.to_string(),
|
AppError::Unauthorized(v) => v.to_string(),
|
||||||
AppError::Forbidden(v) => v.to_string(),
|
AppError::Forbidden(v) => v.to_string(),
|
||||||
AppError::NotFound => "Not found".to_owned(),
|
AppError::NotFound => "Not found".to_owned(),
|
||||||
AppError::InternalError(v) => v.to_string()
|
AppError::InternalError(v) => v.to_string()
|
||||||
}
|
};
|
||||||
|
span.set_tag(|| Tag::new("http.error_msg", msg.clone()));
|
||||||
|
Response::from_data(
|
||||||
|
serde_json::to_vec(&dto::responses::Error {
|
||||||
|
statusCode: code,
|
||||||
|
message: msg
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
@ -165,6 +167,7 @@ fn handle_api_request(span: &mut Span, req: &mut Request, pool: db::DBPool) -> R
|
|||||||
("/api/fs/create_zip", Method::Post, None) => parse_body(span, req).and_then(|v| routes::fs::routes::create_zip(span, req, db, info, v, &pool)),
|
("/api/fs/create_zip", Method::Post, None) => parse_body(span, req).and_then(|v| routes::fs::routes::create_zip(span, req, db, info, v, &pool)),
|
||||||
("/api/fs/download_preview", Method::Get, Some(v)) => routes::fs::routes::download_preview(span, req, db, info, v),
|
("/api/fs/download_preview", Method::Get, Some(v)) => routes::fs::routes::download_preview(span, req, db, info, v),
|
||||||
("/api/fs/get_type", Method::Get, Some(v)) => routes::fs::routes::get_type(span, req, db, info, v),
|
("/api/fs/get_type", Method::Get, Some(v)) => routes::fs::routes::get_type(span, req, db, info, v),
|
||||||
|
("/api/fs/move", Method::Post, None) => parse_body(span, req).and_then(|v| routes::fs::routes::move_node(span, req, db, info, v)),
|
||||||
_ => AppError::NotFound.err()
|
_ => AppError::NotFound.err()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,3 +549,43 @@ pub fn get_type(
|
|||||||
_type: mime_guess::from_path(std::path::Path::new(&node.name)).first_or_octet_stream().to_string()
|
_type: mime_guess::from_path(std::path::Path::new(&node.name)).first_or_octet_stream().to_string()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_node(
|
||||||
|
span: &Span,
|
||||||
|
_: &mut Request,
|
||||||
|
db: &mut DBConnection,
|
||||||
|
info: UserInfo,
|
||||||
|
data: dto::requests::MoveNode
|
||||||
|
) -> Result<ResponseBox, AppError> {
|
||||||
|
let guard_lock = DBConnection::get_lock(info.0.id);
|
||||||
|
let _guard = guard_lock.write(span);
|
||||||
|
|
||||||
|
let target =
|
||||||
|
super::get_node_and_validate(span, &info.0, data.target, db).ok_or(AppError::BadRequest("Invalid target"))?;
|
||||||
|
if target.is_file {
|
||||||
|
return AppError::BadRequest("Invalid target").err();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut nodes = data
|
||||||
|
.nodes
|
||||||
|
.iter()
|
||||||
|
.map(|v| super::get_node_and_validate(span, &info.0, *v, db))
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Option<Vec<db::Inode>>>()
|
||||||
|
.ok_or(AppError::BadRequest("Invalid node"))?;
|
||||||
|
|
||||||
|
for parent in super::get_node_path(span, target.clone(), db) {
|
||||||
|
if nodes.contains(&parent) {
|
||||||
|
return AppError::BadRequest("Can't move node into one of it's subfolders").err();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for child in db.get_children(span, target.id) {
|
||||||
|
if nodes.iter().any(|n| n.name == child.name) {
|
||||||
|
return AppError::BadRequest("Can't overwrite existing file").err();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes.iter_mut().for_each(|n| db.move_node(span, n, target.id));
|
||||||
|
|
||||||
|
get_reply(&dto::responses::Success { statusCode: 200 })
|
||||||
|
}
|
||||||
|
@ -51,6 +51,20 @@ export const create_file = (
|
|||||||
token
|
token
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const move = (
|
||||||
|
token: string,
|
||||||
|
nodes: number[],
|
||||||
|
target: number
|
||||||
|
): Promise<Responses.Success | Responses.Error> =>
|
||||||
|
post_token<Requests.Move>(
|
||||||
|
'/api/fs/move',
|
||||||
|
{
|
||||||
|
nodes: nodes,
|
||||||
|
target: target
|
||||||
|
},
|
||||||
|
token
|
||||||
|
);
|
||||||
|
|
||||||
export const create_zip = (
|
export const create_zip = (
|
||||||
token: string,
|
token: string,
|
||||||
nodes: number[]
|
nodes: number[]
|
||||||
|
@ -60,6 +60,11 @@ export namespace Requests {
|
|||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Move extends Base {
|
||||||
|
nodes: number[];
|
||||||
|
target: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CreateZip extends Base {
|
export interface CreateZip extends Base {
|
||||||
nodes: number[];
|
nodes: number[];
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import type { RouteRecordRaw } from 'vue-router';
|
|||||||
import { createRouter, createWebHistory } from 'vue-router';
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
import LoginView from '@/views/LoginView.vue';
|
import LoginView from '@/views/LoginView.vue';
|
||||||
import SignupView from '@/views/SignupView.vue';
|
import SignupView from '@/views/SignupView.vue';
|
||||||
|
import ForgotPasswordView from '@/views/ForgotPasswordView.vue';
|
||||||
import HomeView from '@/views/HomeView.vue';
|
import HomeView from '@/views/HomeView.vue';
|
||||||
import FSView from '@/views/FSView.vue';
|
import FSView from '@/views/FSView.vue';
|
||||||
import SetTokenView from '@/views/SetTokenView.vue';
|
import SetTokenView from '@/views/SetTokenView.vue';
|
||||||
@ -39,6 +40,11 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
name: 'signup',
|
name: 'signup',
|
||||||
component: SignupView
|
component: SignupView
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/forgot',
|
||||||
|
name: 'forgot',
|
||||||
|
component: ForgotPasswordView
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/fs/:node_id',
|
path: '/fs/:node_id',
|
||||||
name: 'fs',
|
name: 'fs',
|
||||||
|
@ -68,6 +68,10 @@ function signup() {
|
|||||||
router.replace('signup');
|
router.replace('signup');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function forgot() {
|
||||||
|
router.replace('forgot');
|
||||||
|
}
|
||||||
|
|
||||||
function onKey(event: KeyboardEvent) {
|
function onKey(event: KeyboardEvent) {
|
||||||
if (event.key == 'Enter') login();
|
if (event.key == 'Enter') login();
|
||||||
}
|
}
|
||||||
@ -95,10 +99,10 @@ function onKey(event: KeyboardEvent) {
|
|||||||
@keyup="onKey"
|
@keyup="onKey"
|
||||||
/>
|
/>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi span="2" style="text-align: center">
|
<n-gi>
|
||||||
<n-button type="info" @click="login">Login</n-button>
|
<n-button type="info" @click="login">Login</n-button>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi>
|
<n-gi style="text-align: right">
|
||||||
<n-button
|
<n-button
|
||||||
ghost
|
ghost
|
||||||
color="#fc6d27"
|
color="#fc6d27"
|
||||||
@ -111,9 +115,12 @@ function onKey(event: KeyboardEvent) {
|
|||||||
Login with gitlab
|
Login with gitlab
|
||||||
</n-button>
|
</n-button>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi style="text-align: right">
|
<n-gi>
|
||||||
<n-button ghost @click="signup">Signup</n-button>
|
<n-button ghost @click="signup">Signup</n-button>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
|
<n-gi style="text-align: right">
|
||||||
|
<n-button ghost @click="forgot">Forgot password?</n-button>
|
||||||
|
</n-gi>
|
||||||
</n-grid>
|
</n-grid>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
Loading…
Reference in New Issue
Block a user