diff --git a/api/files/files.pb.go b/api/files/files.pb.go index 953a880..c5e7beb 100644 --- a/api/files/files.pb.go +++ b/api/files/files.pb.go @@ -1419,6 +1419,131 @@ func (x *PreviewResp) GetContent() []byte { return nil } +type ActionReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + UserSpacePath string `protobuf:"bytes,2,opt,name=userSpacePath,proto3" json:"userSpacePath,omitempty"` + Action string `protobuf:"bytes,3,opt,name=action,proto3" json:"action,omitempty"` + Destination string `protobuf:"bytes,4,opt,name=destination,proto3" json:"destination,omitempty"` + Override bool `protobuf:"varint,5,opt,name=override,proto3" json:"override,omitempty"` + Rename bool `protobuf:"varint,6,opt,name=rename,proto3" json:"rename,omitempty"` +} + +func (x *ActionReq) Reset() { + *x = ActionReq{} + if protoimpl.UnsafeEnabled { + mi := &file_files_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ActionReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionReq) ProtoMessage() {} + +func (x *ActionReq) ProtoReflect() protoreflect.Message { + mi := &file_files_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActionReq.ProtoReflect.Descriptor instead. +func (*ActionReq) Descriptor() ([]byte, []int) { + return file_files_proto_rawDescGZIP(), []int{22} +} + +func (x *ActionReq) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *ActionReq) GetUserSpacePath() string { + if x != nil { + return x.UserSpacePath + } + return "" +} + +func (x *ActionReq) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *ActionReq) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +func (x *ActionReq) GetOverride() bool { + if x != nil { + return x.Override + } + return false +} + +func (x *ActionReq) GetRename() bool { + if x != nil { + return x.Rename + } + return false +} + +type ActionResp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ActionResp) Reset() { + *x = ActionResp{} + if protoimpl.UnsafeEnabled { + mi := &file_files_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ActionResp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionResp) ProtoMessage() {} + +func (x *ActionResp) ProtoReflect() protoreflect.Message { + mi := &file_files_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActionResp.ProtoReflect.Descriptor instead. +func (*ActionResp) Descriptor() ([]byte, []int) { + return file_files_proto_rawDescGZIP(), []int{23} +} + type SearchResp_Nested struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1431,7 +1556,7 @@ type SearchResp_Nested struct { func (x *SearchResp_Nested) Reset() { *x = SearchResp_Nested{} if protoimpl.UnsafeEnabled { - mi := &file_files_proto_msgTypes[22] + mi := &file_files_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1444,7 +1569,7 @@ func (x *SearchResp_Nested) String() string { func (*SearchResp_Nested) ProtoMessage() {} func (x *SearchResp_Nested) ProtoReflect() protoreflect.Message { - mi := &file_files_proto_msgTypes[22] + mi := &file_files_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1616,43 +1741,59 @@ var file_files_proto_rawDesc = []byte{ 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x27, 0x0a, 0x0b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x32, - 0xaa, 0x04, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x04, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, - 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, - 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, - 0x2f, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, - 0x12, 0x2f, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x22, - 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x2e, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x22, 0x00, 0x12, 0x38, 0x0a, 0x09, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, - 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x09, - 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x2e, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, - 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, - 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x12, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x50, - 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, - 0x2e, 0x2f, 0x3b, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, + 0xb3, 0x01, 0x0a, 0x09, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, + 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x53, 0x70, + 0x61, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x0c, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x32, 0xdb, 0x04, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x04, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x31, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, + 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x10, 0x2e, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x11, + 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x10, 0x2e, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, + 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x10, + 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, + 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, + 0x71, 0x1a, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x09, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x2e, 0x54, 0x75, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, + 0x12, 0x38, 0x0a, 0x09, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x13, 0x2e, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x73, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x11, 0x52, 0x65, + 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, + 0x1b, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, + 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, + 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x12, 0x11, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, + 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, + 0x12, 0x2f, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x2e, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x22, + 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x3b, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1667,7 +1808,7 @@ func file_files_proto_rawDescGZIP() []byte { return file_files_proto_rawDescData } -var file_files_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_files_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_files_proto_goTypes = []interface{}{ (*FileListReq)(nil), // 0: files.FileListReq (*Items)(nil), // 1: files.Items @@ -1691,13 +1832,15 @@ var file_files_proto_goTypes = []interface{}{ (*FileInfoResp)(nil), // 19: files.FileInfoResp (*PreviewReq)(nil), // 20: files.PreviewReq (*PreviewResp)(nil), // 21: files.PreviewResp - (*SearchResp_Nested)(nil), // 22: files.searchResp.Nested + (*ActionReq)(nil), // 22: files.ActionReq + (*ActionResp)(nil), // 23: files.ActionResp + (*SearchResp_Nested)(nil), // 24: files.searchResp.Nested } var file_files_proto_depIdxs = []int32{ 2, // 0: files.FileListReq.sorting:type_name -> files.Sorting 1, // 1: files.FileListResp.items:type_name -> files.Items 2, // 2: files.FileListResp.sorting:type_name -> files.Sorting - 22, // 3: files.searchResp.items:type_name -> files.searchResp.Nested + 24, // 3: files.searchResp.items:type_name -> files.searchResp.Nested 0, // 4: files.File.List:input_type -> files.FileListReq 18, // 5: files.File.Info:input_type -> files.FileInfoReq 4, // 6: files.File.Create:input_type -> files.CreateReq @@ -1708,18 +1851,20 @@ var file_files_proto_depIdxs = []int32{ 14, // 11: files.File.TusUpload:input_type -> files.TusUploadReq 16, // 12: files.File.ResumableTransfer:input_type -> files.ResumableTransferReq 20, // 13: files.File.Preview:input_type -> files.PreviewReq - 3, // 14: files.File.List:output_type -> files.FileListResp - 19, // 15: files.File.Info:output_type -> files.FileInfoResp - 5, // 16: files.File.Create:output_type -> files.CreateResp - 7, // 17: files.File.Delete:output_type -> files.DeleteResp - 11, // 18: files.File.Search:output_type -> files.searchResp - 9, // 19: files.File.Upload:output_type -> files.UploadResp - 13, // 20: files.File.TusCreate:output_type -> files.TusCreateResp - 15, // 21: files.File.TusUpload:output_type -> files.TusUploadResp - 17, // 22: files.File.ResumableTransfer:output_type -> files.ResumableTransferResp - 21, // 23: files.File.Preview:output_type -> files.PreviewResp - 14, // [14:24] is the sub-list for method output_type - 4, // [4:14] is the sub-list for method input_type + 22, // 14: files.File.Action:input_type -> files.ActionReq + 3, // 15: files.File.List:output_type -> files.FileListResp + 19, // 16: files.File.Info:output_type -> files.FileInfoResp + 5, // 17: files.File.Create:output_type -> files.CreateResp + 7, // 18: files.File.Delete:output_type -> files.DeleteResp + 11, // 19: files.File.Search:output_type -> files.searchResp + 9, // 20: files.File.Upload:output_type -> files.UploadResp + 13, // 21: files.File.TusCreate:output_type -> files.TusCreateResp + 15, // 22: files.File.TusUpload:output_type -> files.TusUploadResp + 17, // 23: files.File.ResumableTransfer:output_type -> files.ResumableTransferResp + 21, // 24: files.File.Preview:output_type -> files.PreviewResp + 23, // 25: files.File.Action:output_type -> files.ActionResp + 15, // [15:26] is the sub-list for method output_type + 4, // [4:15] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name 4, // [4:4] is the sub-list for extension extendee 0, // [0:4] is the sub-list for field type_name @@ -1996,6 +2141,30 @@ func file_files_proto_init() { } } file_files_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ActionReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_files_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ActionResp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_files_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SearchResp_Nested); i { case 0: return &v.state @@ -2014,7 +2183,7 @@ func file_files_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_files_proto_rawDesc, NumEnums: 0, - NumMessages: 23, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/api/files/files.proto b/api/files/files.proto index 1b09c93..1c30830 100644 --- a/api/files/files.proto +++ b/api/files/files.proto @@ -11,15 +11,16 @@ service File{ rpc Delete(DeleteReq) returns (DeleteResp) {} // 删除文件或文件夹 rpc Search(searchReq) returns (searchResp) {} // 搜索 rpc Upload(UploadReq) returns (UploadResp) {} // 文件上传 - rpc TusCreate(TusCreateReq) returns(TusCreateResp) {} // 分块文件上传:创建文件 - rpc TusUpload(TusUploadReq) returns(TusUploadResp) {} // 分块文件上传:上传文件块 - rpc ResumableTransfer(ResumableTransferReq) returns(ResumableTransferResp) {} // 断点续传的grpc实现 - rpc Preview(PreviewReq) returns(PreviewResp) {} // 文件预览 + rpc TusCreate(TusCreateReq) returns (TusCreateResp) {} // 分块文件上传:创建文件 + rpc TusUpload(TusUploadReq) returns (TusUploadResp) {} // 分块文件上传:上传文件块 + rpc ResumableTransfer(ResumableTransferReq) returns (ResumableTransferResp) {} // 断点续传的grpc实现 + rpc Preview(PreviewReq) returns (PreviewResp) {} // 文件预览 + rpc Action(ActionReq) returns (ActionResp) {} // 移动文件或重命名文件 } message FileListReq{ string path = 1; // 目标文件夹路径 - string UserSpacePath = 2; // 用户空间的路径 + string userSpacePath = 2; // 用户空间的路径 Sorting sorting = 3; } @@ -161,4 +162,18 @@ message PreviewReq{ message PreviewResp{ bytes content = 1; -} \ No newline at end of file +} + +message ActionReq{ + string path = 1; + string userSpacePath = 2; + string action = 3; + string destination = 4; + bool override = 5; + bool rename = 6; +} + +message ActionResp{ + +} + diff --git a/api/files/files.validator.pb.go b/api/files/files.validator.pb.go index acdd7e1..350ceae 100644 --- a/api/files/files.validator.pb.go +++ b/api/files/files.validator.pb.go @@ -108,3 +108,9 @@ func (this *PreviewReq) Validate() error { func (this *PreviewResp) Validate() error { return nil } +func (this *ActionReq) Validate() error { + return nil +} +func (this *ActionResp) Validate() error { + return nil +} diff --git a/api/files/files_triple.pb.go b/api/files/files_triple.pb.go index 8963acf..9f8a95f 100644 --- a/api/files/files_triple.pb.go +++ b/api/files/files_triple.pb.go @@ -38,6 +38,7 @@ type FileClient interface { TusUpload(ctx context.Context, in *TusUploadReq, opts ...grpc_go.CallOption) (*TusUploadResp, common.ErrorWithAttachment) ResumableTransfer(ctx context.Context, in *ResumableTransferReq, opts ...grpc_go.CallOption) (*ResumableTransferResp, common.ErrorWithAttachment) Preview(ctx context.Context, in *PreviewReq, opts ...grpc_go.CallOption) (*PreviewResp, common.ErrorWithAttachment) + Action(ctx context.Context, in *ActionReq, opts ...grpc_go.CallOption) (*ActionResp, common.ErrorWithAttachment) } type fileClient struct { @@ -55,6 +56,7 @@ type FileClientImpl struct { TusUpload func(ctx context.Context, in *TusUploadReq) (*TusUploadResp, error) ResumableTransfer func(ctx context.Context, in *ResumableTransferReq) (*ResumableTransferResp, error) Preview func(ctx context.Context, in *PreviewReq) (*PreviewResp, error) + Action func(ctx context.Context, in *ActionReq) (*ActionResp, error) } func (c *FileClientImpl) GetDubboStub(cc *triple.TripleConn) FileClient { @@ -129,6 +131,12 @@ func (c *fileClient) Preview(ctx context.Context, in *PreviewReq, opts ...grpc_g return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Preview", in, out) } +func (c *fileClient) Action(ctx context.Context, in *ActionReq, opts ...grpc_go.CallOption) (*ActionResp, common.ErrorWithAttachment) { + out := new(ActionResp) + interfaceKey := ctx.Value(constant.InterfaceKey).(string) + return out, c.cc.Invoke(ctx, "/"+interfaceKey+"/Action", in, out) +} + // FileServer is the server API for File service. // All implementations must embed UnimplementedFileServer // for forward compatibility @@ -143,6 +151,7 @@ type FileServer interface { TusUpload(context.Context, *TusUploadReq) (*TusUploadResp, error) ResumableTransfer(context.Context, *ResumableTransferReq) (*ResumableTransferResp, error) Preview(context.Context, *PreviewReq) (*PreviewResp, error) + Action(context.Context, *ActionReq) (*ActionResp, error) mustEmbedUnimplementedFileServer() } @@ -181,6 +190,9 @@ func (UnimplementedFileServer) ResumableTransfer(context.Context, *ResumableTran func (UnimplementedFileServer) Preview(context.Context, *PreviewReq) (*PreviewResp, error) { return nil, status.Errorf(codes.Unimplemented, "method Preview not implemented") } +func (UnimplementedFileServer) Action(context.Context, *ActionReq) (*ActionResp, error) { + return nil, status.Errorf(codes.Unimplemented, "method Action not implemented") +} func (s *UnimplementedFileServer) XXX_SetProxyImpl(impl protocol.Invoker) { s.proxyImpl = impl } @@ -499,6 +511,35 @@ func _File_Preview_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _File_Action_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc_go.UnaryServerInterceptor) (interface{}, error) { + in := new(ActionReq) + if err := dec(in); err != nil { + return nil, err + } + base := srv.(dubbo3.Dubbo3GrpcService) + args := []interface{}{} + args = append(args, in) + md, _ := metadata.FromIncomingContext(ctx) + invAttachment := make(map[string]interface{}, len(md)) + for k, v := range md { + invAttachment[k] = v + } + invo := invocation.NewRPCInvocation("Action", args, invAttachment) + if interceptor == nil { + result := base.XXX_GetProxyImpl().Invoke(ctx, invo) + return result, result.Error() + } + info := &grpc_go.UnaryServerInfo{ + Server: srv, + FullMethod: ctx.Value("XXX_TRIPLE_GO_INTERFACE_NAME").(string), + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + result := base.XXX_GetProxyImpl().Invoke(ctx, invo) + return result, result.Error() + } + return interceptor(ctx, in, info, handler) +} + // File_ServiceDesc is the grpc_go.ServiceDesc for File service. // It's only intended for direct use with grpc_go.RegisterService, // and not to be introspected or modified (even as a copy) @@ -546,6 +587,10 @@ var File_ServiceDesc = grpc_go.ServiceDesc{ MethodName: "Preview", Handler: _File_Preview_Handler, }, + { + MethodName: "Action", + Handler: _File_Action_Handler, + }, }, Streams: []grpc_go.StreamDesc{}, Metadata: "files.proto", diff --git a/service/files.go b/service/files.go index 3aa94ea..8ff2f33 100644 --- a/service/files.go +++ b/service/files.go @@ -7,12 +7,15 @@ import ( "fmt" "io" "os" + "path" "path/filepath" "strings" "dubbo.apache.org/dubbo-go/v3/common/logger" filesApi "github.com/filebrowser/filebrowser/v2/api/files" + fbErrors "github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/files" + "github.com/filebrowser/filebrowser/v2/fileutils" "github.com/filebrowser/filebrowser/v2/http" "github.com/filebrowser/filebrowser/v2/img" "github.com/filebrowser/filebrowser/v2/rules" @@ -311,7 +314,7 @@ func (f *FilesProvider) Preview(ctx context.Context, req *filesApi.PreviewReq) ( } } -func (f *FilesProvider) createPreview(imgSvc http.ImgService, +func ( *FilesProvider) createPreview(imgSvc http.ImgService, file *files.FileInfo, previewSize uint32) ([]byte, error) { fd, err := file.Fs.Open(file.Path) if err != nil { @@ -344,6 +347,27 @@ func (f *FilesProvider) createPreview(imgSvc http.ImgService, } return buf.Bytes(), nil } + +func (f *FilesProvider) Action(_ context.Context, req *filesApi.ActionReq) (*filesApi.ActionResp, error) { + fs := getFs(req.UserSpacePath) + if req.Destination == "/" || req.Path == "/" { + return nil, errors.New("禁止操作用户空间根目录") + } + err := checkParent(req.Path, req.Destination) + if err != nil { + return nil, err + } + if !req.Override && !req.Rename { + if _, err = fs.Stat(req.Destination); err == nil { + return nil, err + } + } + if req.Rename { + req.Destination = addVersionSuffix(req.Destination, fs) + } + return &filesApi.ActionResp{}, patchAction(req.Action, req.Path, req.Destination, fs) +} + func getFs(UserSpacePath string) afero.Fs { bashAbs, _ := filepath.Abs(BASE_PATH) if !strings.HasPrefix(UserSpacePath, "/") { @@ -351,3 +375,61 @@ func getFs(UserSpacePath string) afero.Fs { } return afero.NewBasePathFs(afero.NewOsFs(), bashAbs+UserSpacePath) } + +func checkParent(src, dst string) error { + rel, err := filepath.Rel(src, dst) + if err != nil { + return err + } + + rel = filepath.ToSlash(rel) + if !strings.HasPrefix(rel, "../") && rel != ".." && rel != "." { + return fbErrors.ErrSourceIsParent + } + + return nil +} + +func addVersionSuffix(source string, fs afero.Fs) string { + counter := 1 + dir, name := path.Split(source) + ext := filepath.Ext(name) + base := strings.TrimSuffix(name, ext) + + for { + if _, err := fs.Stat(source); err != nil { + break + } + renamed := fmt.Sprintf("%s(%d)%s", base, counter, ext) + source = path.Join(dir, renamed) + counter++ + } + + return source +} + +func patchAction(action, src, dst string, fs afero.Fs) error { + switch action { + case "copy": + return fileutils.Copy(fs, src, dst) + case "rename": + src = path.Clean("/" + src) + dst = path.Clean("/" + dst) + + _, err := files.NewFileInfo(&files.FileOptions{ + Fs: fs, + Path: src, + Modify: true, + Expand: false, + ReadHeader: false, + Checker: rules.EmptyChecker, + }) + if err != nil { + return err + } + + return fileutils.MoveFile(fs, src, dst) + default: + return fmt.Errorf("unsupported action %s: %w", action, fbErrors.ErrInvalidRequestParams) + } +}