1401 lines
44 KiB
Go
1401 lines
44 KiB
Go
package localserver
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/pion/webrtc/v3"
|
|
)
|
|
|
|
const (
|
|
CREATE_FOLDER = "create_folder"
|
|
COPY_FOLDER = "copy_folder"
|
|
COPY_FILE = "copy_file"
|
|
CUT_FILE = "cut_file"
|
|
CUT_FOLDER = "cut_folder"
|
|
RENAME_FOLDER = "rename_folder"
|
|
RENAME_FILE = "rename_file"
|
|
DELETE_FOLDER = "delete_folder"
|
|
DELETE_FILE = "delete_file"
|
|
UPDATE_PERMISSIONS = "update_permissions"
|
|
GET_FS_ENTITIES = "get_fs_entities"
|
|
ADD_FS_ENTITY_MEMBERS = "add_fs_entity_members"
|
|
REMOVE_FS_ENTITY_MEMBERS = "remove_fs_entity_members"
|
|
ZONE_UPLOAD_FILE = "zone_upload_file"
|
|
ZONE_DOWNLOAD_FILE = "zone_download_file"
|
|
)
|
|
|
|
const (
|
|
CREATE_FOLDER_DONE = "create_folder_done"
|
|
CREATE_FILE_DONE = "create_file_done"
|
|
COPY_FOLDER_DONE = "copy_folder_done"
|
|
COPY_FILE_DONE = "copy_file_done"
|
|
CUT_FILE_DONE = "cut_file_done"
|
|
CUT_FOLDER_DONE = "cut_folder_done"
|
|
RENAME_FOLDER_DONE = "rename_folder_done"
|
|
RENAME_FILE_DONE = "rename_file_done"
|
|
DELETE_FOLDER_DONE = "delete_folder_done"
|
|
DELETE_FILE_DONE = "delete_file_done"
|
|
UPDATE_PERMISSIONS_DONE = "update_permissions_done"
|
|
GET_FS_ENTITIES_DONE = "get_fs_entities_done"
|
|
ADD_FS_ENTITY_MEMBERS_DONE = "add_fs_entity_members_done"
|
|
REMOVE_FS_ENTITY_MEMBERS_DONE = "remove_fs_entity_members_done"
|
|
ZONE_DOWNLOAD_FILE_DONE = "zone_download_file_done"
|
|
ZONE_UPLOAD_FILE_DONE = "zone_upload_file_done"
|
|
)
|
|
|
|
const (
|
|
PARENT = "parent"
|
|
)
|
|
|
|
// ZoneFileHandler : Handle all interaction of the node zone related to the file system
|
|
type ZoneFileHandler[T ZippytalFSInstance] struct {
|
|
ZoneId string
|
|
HostId string
|
|
ZoneMembersId []string
|
|
DataChannels map[string]*DataChannel
|
|
FileDataChannels map[string]*DataChannel
|
|
FileDataChannelsFlag *uint32
|
|
Flag *uint32
|
|
FSInstanceFlag *uint32
|
|
Publishers []<-chan *ZoneRequest
|
|
FSInstance T
|
|
reqChans []chan<- *ZoneRequest
|
|
DB *ZoneFilesDBHandler
|
|
}
|
|
|
|
// FSEntityAccessRights : representation of the different rights users can have on a ZoneFSEntity
|
|
type FSEntityAccessRights struct {
|
|
// Read : this field for folder determine if the member is allowed to see this folder only because he is allowed to read a child folder or because he actually is authorized to read this folder (hard to explain)
|
|
Read bool `json:"read"`
|
|
// Write : this field for folder determine if the user can upload file in this folder and for file if the user can edit the file (future feature).
|
|
Write bool `json:"write"`
|
|
// Download : this field for folder determine if the user can download a zip of the folder (future feature) and for file if he can download the file.
|
|
Download bool `json:"download"`
|
|
// Rename : determine the ability of the user to change the name of the fsEntity
|
|
Rename bool `json:"rename"`
|
|
}
|
|
|
|
// ZoneFSEntity : representation of a FSEntity (file or folder) for the zone fs feature
|
|
type ZoneFSEntity struct {
|
|
Name string `json:"name"`
|
|
Owner string `json:"owner"`
|
|
Type string `json:"type"`
|
|
Folder bool `json:"folder"`
|
|
ModTime string `json:"modTime"`
|
|
CreationTime string `json:"creationTime"`
|
|
Size uint64 `json:"size"`
|
|
Members map[string]*FSEntityAccessRights `json:"members"`
|
|
}
|
|
|
|
// NewZoneFileHandler: factory function to create a zone file handler the name of the parameters are explicit, this is the only way to safely create a ZoneFSEntity
|
|
func NewZoneFileHandler(_ string, zoneId string, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneFileHandler *ZoneFileHandler[*FSInstance], err error) {
|
|
db, err := NewZoneFilesDBHandler(zoneId)
|
|
if err != nil {
|
|
return
|
|
}
|
|
initFsDirectory := func(u string) (err error) {
|
|
logger.Printf("creating fs directory for user %s...\n", u)
|
|
baseConfig := ZoneFSEntity{
|
|
Name: u,
|
|
Owner: u,
|
|
Type: "private",
|
|
Folder: true,
|
|
Members: map[string]*FSEntityAccessRights{
|
|
u: {
|
|
Read: true,
|
|
Write: true,
|
|
Download: true,
|
|
Rename: true,
|
|
},
|
|
},
|
|
}
|
|
err = db.AddNewFSEntity("", &baseConfig)
|
|
return
|
|
}
|
|
if _, dirErr := os.ReadDir(filepath.Join(dataPath, "data", "zones", zoneId, "fs")); os.IsNotExist(dirErr) {
|
|
dirErr := os.MkdirAll(filepath.Join(dataPath, "data", "zones", zoneId, "fs"), 0700)
|
|
if dirErr != nil {
|
|
return
|
|
}
|
|
}
|
|
for _, user := range authorizedMembers {
|
|
if _, dirErr := os.ReadDir(filepath.Join(dataPath, "data", "zones", zoneId, "fs", user)); os.IsNotExist(dirErr) {
|
|
if e := initFsDirectory(user); e != nil {
|
|
logger.Println(e)
|
|
}
|
|
}
|
|
}
|
|
fSInstanceFlag := uint32(0)
|
|
fSDCFlag := uint32(0)
|
|
fsInstance := NewFSInstance(zoneId, owner, authorizedMembers)
|
|
zoneFileHandler = &ZoneFileHandler[*FSInstance]{
|
|
ZoneId: zoneId,
|
|
ZoneMembersId: authorizedMembers,
|
|
DataChannels: dataChannels,
|
|
FileDataChannels: make(map[string]*DataChannel),
|
|
FileDataChannelsFlag: &fSDCFlag,
|
|
FSInstanceFlag: &fSInstanceFlag,
|
|
FSInstance: fsInstance,
|
|
DB: db,
|
|
Flag: flag,
|
|
}
|
|
return
|
|
}
|
|
|
|
// func (zfh *ZoneFileHandler) sendZoneRequest(reqType string, from string, payload map[string]interface{}) {
|
|
// go func() {
|
|
// for _, rc := range zfh.reqChans {
|
|
// rc <- &ZoneRequest{
|
|
// ReqType: reqType,
|
|
// From: from,
|
|
// Payload: payload,
|
|
// }
|
|
// }
|
|
// }()
|
|
// }
|
|
|
|
func (zfh *ZoneFileHandler[T]) Init(ctx context.Context, authorizedMembers []string) (err error) {
|
|
for _, member := range authorizedMembers {
|
|
if serr := zfh.SetPublicRootFolders(member); serr != nil {
|
|
logger.Println(serr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) sendDataChannelMessage(reqType string, from string, to string, payload map[string]interface{}) (<-chan struct{}, <-chan error) {
|
|
done, errCh := make(chan struct{}), make(chan error)
|
|
go func() {
|
|
if err := atomicallyExecute(zfh.FileDataChannelsFlag, func() (err error) {
|
|
if _, ok := zfh.FileDataChannels[to]; ok {
|
|
bs, jsonErr := json.Marshal(&ZoneResponse{
|
|
Type: reqType,
|
|
From: from,
|
|
To: to,
|
|
Payload: payload,
|
|
})
|
|
if jsonErr != nil {
|
|
return jsonErr
|
|
}
|
|
<-time.After(20 * time.Millisecond)
|
|
err = zfh.FileDataChannels[to].DataChannel.SendText(string(bs))
|
|
}
|
|
return
|
|
}); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
done <- struct{}{}
|
|
}()
|
|
return done, errCh
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) sendZoneRequest(reqType string, from string, payload map[string]interface{}) {
|
|
go func() {
|
|
for _, rc := range zfh.reqChans {
|
|
rc <- &ZoneRequest{
|
|
ReqType: reqType,
|
|
From: from,
|
|
Payload: payload,
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) Subscribe(ctx context.Context, publisher <-chan *ZoneRequest) (reqChan chan *ZoneRequest, done chan struct{}, errCh chan error) {
|
|
reqChan, done, errCh = make(chan *ZoneRequest), make(chan struct{}), make(chan error)
|
|
zfh.reqChans = append(zfh.reqChans, reqChan)
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
done <- struct{}{}
|
|
return
|
|
case req := <-publisher:
|
|
if err := zfh.handleZoneRequest(ctx, req); err != nil {
|
|
errCh <- err
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
return
|
|
}
|
|
|
|
// func (zfh *ZoneFileHandler[T]) signalCandidate(from string, to string, candidate *webrtc.ICECandidate) (err error) {
|
|
// d, e := zfh.sendDataChannelMessage(string(ZONE_FS_WEBRTC_CANDIDATE), from, to, map[string]interface{}{
|
|
// "from": from,
|
|
// "to": to,
|
|
// "candidate": candidate.ToJSON().Candidate,
|
|
// "sdpMid": *candidate.ToJSON().SDPMid,
|
|
// "sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)),
|
|
// })
|
|
// select {
|
|
// case <-d:
|
|
// case err = <-e:
|
|
// }
|
|
// return
|
|
// }
|
|
|
|
// GetFSEntities: Return a list of ZoneFSEntity to the user with the provided userId
|
|
func (zfh *ZoneFileHandler[T]) GetFSEntities(userId string, section string, basePath string, limit int, lastIndex int, backward bool) (err error) {
|
|
var fsEntities []*ZoneFSEntity
|
|
var currentPath string = basePath
|
|
var listFSEntities func(string, string, int, int, bool)
|
|
listFSEntities = func(userId, path string, limit, lastIndex int, backward bool) {
|
|
fsEntities, _, err = zfh.DB.ListZoneFSEntity(path, userId, lastIndex, limit)
|
|
if err != nil {
|
|
return
|
|
}
|
|
currentPath = path
|
|
if len(fsEntities) == 1 {
|
|
if rights, ok := fsEntities[0].Members[userId]; ok {
|
|
if !rights.Read {
|
|
if !backward {
|
|
listFSEntities(userId, filepath.Join(path, fsEntities[0].Name), 100, 0, backward)
|
|
} else {
|
|
splittedPath := filepath.SplitList(path)
|
|
if len(splittedPath) > 1 {
|
|
listFSEntities(userId, filepath.Dir(path), 100, 0, backward)
|
|
} else {
|
|
listFSEntities(userId, "", 100, 0, backward)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
listFSEntities(userId, basePath, 100, 0, backward)
|
|
var parent *ZoneFSEntity
|
|
if len(filepath.SplitList(basePath)) > 0 {
|
|
parent, err = zfh.DB.GetFSEntity(filepath.Dir(basePath), filepath.Base(basePath))
|
|
if err != nil {
|
|
return
|
|
}
|
|
logger.Println("------------------ parent is --------------")
|
|
logger.Println(parent)
|
|
}
|
|
done, errCh := zfh.sendDataChannelMessage(GET_FS_ENTITIES, "node", userId, map[string]interface{}{
|
|
"fsEntities": fsEntities,
|
|
"parent": parent,
|
|
"currentPath": currentPath,
|
|
"section": section,
|
|
})
|
|
select {
|
|
case <-done:
|
|
fmt.Println("done fs entity get")
|
|
case err = <-errCh:
|
|
}
|
|
return
|
|
}
|
|
|
|
// CreateFolder: create a ZoneFSEntity folder mapped to a real folder on the disk
|
|
func (zfh *ZoneFileHandler[T]) CreateFolder(path string, config *ZoneFSEntity) (err error) {
|
|
if config.Type == PARENT {
|
|
parentPath := filepath.Dir(path)
|
|
parentFolderName := filepath.Base(path)
|
|
logger.Println(parentPath, "-------", parentFolderName)
|
|
var folder *ZoneFSEntity
|
|
if len(parentPath) > 1 {
|
|
folder, err = zfh.DB.GetFSEntity(parentPath, parentFolderName)
|
|
} else {
|
|
folder, err = zfh.DB.GetFSEntity("", parentFolderName)
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
config.Members = make(map[string]*FSEntityAccessRights)
|
|
for k, v := range folder.Members {
|
|
config.Members[k] = &FSEntityAccessRights{
|
|
Read: v.Read,
|
|
Write: v.Write,
|
|
Download: v.Download,
|
|
Rename: v.Rename,
|
|
}
|
|
}
|
|
}
|
|
if err = zfh.DB.AddNewFSEntity(path, config); err != nil {
|
|
return
|
|
}
|
|
for member := range config.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(CREATE_FOLDER_DONE, "node", member, map[string]interface{}{
|
|
"path": path,
|
|
"fsEntity": config,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case err = <-errCh:
|
|
logger.Println(err)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// CreateFile: create a ZoneFSEntity file mapped to a real file on the disk
|
|
func (zfh *ZoneFileHandler[T]) CreateFile(path, fileName string, config *ZoneFSEntity) (err error) {
|
|
splittedPath := strings.Split(path, "/")
|
|
if config.Type == PARENT {
|
|
logger.Println(strings.Join(splittedPath[:len(splittedPath)-1], "/"), "-------", splittedPath[len(splittedPath)-1])
|
|
var folder *ZoneFSEntity
|
|
if len(splittedPath) > 1 {
|
|
folder, err = zfh.DB.GetFSEntity(strings.Join(splittedPath[:len(splittedPath)-1], "/"), splittedPath[len(splittedPath)-1])
|
|
} else {
|
|
folder, err = zfh.DB.GetFSEntity("", splittedPath[0])
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
config.Members = make(map[string]*FSEntityAccessRights)
|
|
for k, v := range folder.Members {
|
|
config.Members[k] = &FSEntityAccessRights{
|
|
Read: v.Read,
|
|
Write: v.Write,
|
|
Download: v.Download,
|
|
Rename: v.Rename,
|
|
}
|
|
}
|
|
}
|
|
if err = zfh.DB.AddNewFSEntity(path, config); err != nil {
|
|
return
|
|
}
|
|
for member := range config.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(CREATE_FILE_DONE, "node", member, map[string]interface{}{
|
|
"path": path,
|
|
"fsEntity": config,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case err = <-errCh:
|
|
logger.Println(err)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// EditFolderType: change the type of the folder and modify rights of the users according to the new ZoneFSEntity type provided
|
|
func (zfh *ZoneFileHandler[T]) EditFolderType(userId string, path string, folderName string, newFolderType string) (err error) {
|
|
folder, err := zfh.DB.GetFSEntity(path, folderName)
|
|
if err != nil {
|
|
return
|
|
}
|
|
folder.Type = newFolderType
|
|
if err = zfh.DB.SetFSEntity(path, folderName, folder); err != nil {
|
|
return
|
|
}
|
|
done, errCh := zfh.sendDataChannelMessage("", "node", userId, map[string]interface{}{
|
|
"newFolder": folder,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case err = <-errCh:
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) EditFileType(path string, fileName string, newFileType string) (err error) {
|
|
return
|
|
}
|
|
|
|
// AddFolderMember: add a list of members to the map of users allowed to access the folder with the provided folderName and set the rights
|
|
func (zfh *ZoneFileHandler[T]) AddFolderMember(userId string, path string, folderName string, members []interface{}, read bool, write bool, download bool, rename bool) (err error) {
|
|
var addMembersDb func(string, string, bool, bool, bool, bool, bool) (folder *ZoneFSEntity, err error)
|
|
addMembersDb = func(path string, folderName string, read bool, write bool, download bool, rename bool, init bool) (folder *ZoneFSEntity, err error) {
|
|
folder, err = zfh.DB.GetFSEntity(path, folderName)
|
|
if err != nil {
|
|
return
|
|
}
|
|
childrens := make([]*ZoneFSEntity, 0)
|
|
if init {
|
|
childrens, _, err = zfh.DB.ListZoneFSEntity(filepath.Join(path, folderName), userId, 0, 100)
|
|
if err != nil {
|
|
logger.Println("cannot get siblings folders:", err)
|
|
return
|
|
}
|
|
}
|
|
for _, newMember := range members {
|
|
if m, ok := newMember.(string); ok {
|
|
if _, ok := folder.Members[m]; !ok {
|
|
folder.Members[m] = &FSEntityAccessRights{
|
|
Read: read,
|
|
Write: write,
|
|
Download: download,
|
|
Rename: rename,
|
|
}
|
|
}
|
|
if init {
|
|
go func() {
|
|
for _, children := range childrens {
|
|
logger.Println("------:", filepath.Join(path, folderName), "-", children.Name)
|
|
if children.Type != "private" {
|
|
if _, err = addMembersDb(filepath.Join(path, folderName), children.Name, read, write, download, rename, true); err != nil {
|
|
logger.Println("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
|
|
logger.Println("error from ttttthheeere:", err)
|
|
logger.Println("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
}
|
|
}
|
|
err = zfh.DB.SetFSEntity(path, folderName, folder)
|
|
return
|
|
}
|
|
folder, err := addMembersDb(path, folderName, read, write, download, rename, true)
|
|
if err != nil {
|
|
return
|
|
}
|
|
splittedPath := strings.Split(path, "/")
|
|
for i := 1; i <= len(splittedPath); i++ {
|
|
logger.Println(i)
|
|
var addErr error
|
|
if i == len(splittedPath) {
|
|
_, addErr = addMembersDb("", splittedPath[0], false, false, false, false, false)
|
|
|
|
} else {
|
|
_, addErr = addMembersDb(strings.Join(splittedPath[:len(splittedPath)-i], "/"), splittedPath[len(splittedPath)-i], false, false, false, false, false)
|
|
|
|
}
|
|
if addErr != nil {
|
|
logger.Println(addErr)
|
|
break
|
|
}
|
|
}
|
|
for member := range folder.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(ADD_FS_ENTITY_MEMBERS_DONE, "node", member, map[string]interface{}{
|
|
"path": path,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
for _, member := range members {
|
|
go func(m string) {
|
|
bs, err := json.Marshal(map[string]any{
|
|
"zoneId": zfh.ZoneId,
|
|
"folderName": folderName,
|
|
"folderPath": path,
|
|
"zoneHost": NodeID,
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
zfh.sendZoneRequest(CREATE_NOTIFICATION, "node", map[string]interface{}{
|
|
"type": "added_in_folder",
|
|
"title": "New folder shared 📁",
|
|
"body": fmt.Sprintf("%s granted you access to the folder %s", userId, folderName),
|
|
"isPushed": true,
|
|
"payload": string(bs),
|
|
"recipients": []string{m},
|
|
})
|
|
}(member.(string))
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) AddFileMember(path string, filename string, members []interface{}, read bool, write bool, download bool, rename bool) (err error) {
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) RemoveFolderMember(userId string, path string, folderName string, members []interface{}) (err error) {
|
|
membersM := make(map[string]bool)
|
|
staticMembersM := make(map[string]bool)
|
|
for _, member := range members {
|
|
if m, ok := member.(string); ok {
|
|
membersM[m] = true
|
|
staticMembersM[m] = true
|
|
}
|
|
}
|
|
var removeChildMemberDb func(string, string) (folder *ZoneFSEntity, err error)
|
|
removeChildMemberDb = func(path, folderName string) (folder *ZoneFSEntity, err error) {
|
|
childrens, _, err := zfh.DB.ListZoneFSEntity(filepath.Join(path, folderName), userId, 0, 100)
|
|
if err != nil {
|
|
logger.Println("cannot get siblings folders:", err)
|
|
return
|
|
}
|
|
go func() {
|
|
for _, children := range childrens {
|
|
for member := range staticMembersM {
|
|
if _, ok := children.Members[member]; ok && member != children.Owner {
|
|
delete(children.Members, member)
|
|
}
|
|
}
|
|
logger.Println("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
|
|
logger.Println(filepath.Join(path, folderName), ":", children.Name)
|
|
logger.Println("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
|
|
_, _ = removeChildMemberDb(filepath.Join(path, folderName), children.Name)
|
|
err = zfh.DB.SetFSEntity(filepath.Join(path, folderName), children.Name, children)
|
|
}
|
|
}()
|
|
return
|
|
}
|
|
removeMemberDb := func(path, folderName string, init bool) (folder *ZoneFSEntity, err error) {
|
|
folder, err = zfh.DB.GetFSEntity(path, folderName)
|
|
if err != nil {
|
|
return
|
|
}
|
|
siblings, _, err := zfh.DB.ListZoneFSEntity(path, userId, 0, 100)
|
|
if err != nil {
|
|
logger.Println("cannot get siblings folders:", err)
|
|
return
|
|
}
|
|
if init {
|
|
_, _ = removeChildMemberDb(path, folderName)
|
|
}
|
|
for member := range membersM {
|
|
if _, ok := folder.Members[member]; ok && member != folder.Owner {
|
|
if !folder.Members[member].Read || init {
|
|
delete(folder.Members, member)
|
|
} else {
|
|
delete(membersM, member)
|
|
}
|
|
for _, sibling := range siblings {
|
|
if sibling.Name != folder.Name {
|
|
if _, ok := sibling.Members[member]; ok {
|
|
delete(membersM, member)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
err = zfh.DB.SetFSEntity(path, folderName, folder)
|
|
return
|
|
}
|
|
folder, err := removeMemberDb(path, folderName, true)
|
|
if err != nil {
|
|
return
|
|
}
|
|
splittedPath := strings.Split(path, "/")
|
|
for i := 1; i <= len(splittedPath) && len(membersM) > 0; i++ {
|
|
logger.Println(i)
|
|
var addErr error
|
|
if i == len(splittedPath) {
|
|
_, addErr = removeMemberDb("", splittedPath[0], false)
|
|
|
|
} else {
|
|
_, addErr = removeMemberDb(strings.Join(splittedPath[:len(splittedPath)-i], "/"), splittedPath[len(splittedPath)-i], false)
|
|
|
|
}
|
|
if addErr != nil {
|
|
logger.Println(addErr)
|
|
break
|
|
}
|
|
}
|
|
for member := range folder.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(REMOVE_FS_ENTITY_MEMBERS_DONE, "node", member, map[string]interface{}{
|
|
"path": filepath.Join(path, folderName),
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
for _, member := range members {
|
|
if _, ok := member.(string); ok {
|
|
go func(m string) {
|
|
fmt.Println("sending unshare notification", m)
|
|
bs, err := json.Marshal(map[string]any{
|
|
"zoneId": zfh.ZoneId,
|
|
"folderName": folderName,
|
|
"zoneHost": NodeID,
|
|
})
|
|
if err != nil {
|
|
fmt.Println("error there", err)
|
|
return
|
|
}
|
|
zfh.sendZoneRequest(CREATE_NOTIFICATION, "node", map[string]interface{}{
|
|
"type": "removed_from_folder",
|
|
"title": "Folder unshared ⛔️",
|
|
"body": fmt.Sprintf("%s stopped your access to the folder %s", userId, folderName),
|
|
"isPushed": true,
|
|
"payload": string(bs),
|
|
"recipients": []string{m},
|
|
})
|
|
}(member.(string))
|
|
done, errCh := zfh.sendDataChannelMessage(REMOVE_FS_ENTITY_MEMBERS_DONE, "node", member.(string), map[string]interface{}{
|
|
"path": filepath.Join(path, folderName),
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) RemoveFileMember(path, filename, members, read, write, download, rename bool) (err error) {
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) ClearUserFolders(userId string) (err error) {
|
|
fsEntities, _, err := zfh.DB.ListZoneFSEntity("", userId, 0, 100)
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, fsEntity := range fsEntities {
|
|
go func(f *ZoneFSEntity) {
|
|
if e := zfh.RemoveFolderMember(f.Owner, "", f.Name, []any{userId}); e != nil {
|
|
logger.Println(e)
|
|
}
|
|
}(fsEntity)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) RenameFolder(path, currentName, newName string) (err error) {
|
|
fsEntity, err := zfh.DB.GetFSEntity(path, currentName)
|
|
if err != nil {
|
|
return
|
|
}
|
|
fsEntity.Name = newName
|
|
if err = os.Rename(filepath.Join(filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs"), path, currentName), filepath.Join(filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs"), path, newName)); err != nil {
|
|
return
|
|
}
|
|
if err = zfh.DB.SetFSEntity(path, currentName, fsEntity); err != nil {
|
|
return
|
|
}
|
|
for member := range fsEntity.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(RENAME_FOLDER_DONE, "node", member, map[string]interface{}{
|
|
"path": filepath.Join(path, newName),
|
|
"folderId": newName,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) RenameFile(path, currentName, newName string) (err error) {
|
|
fsEntity, err := zfh.DB.GetFSEntity(path, currentName)
|
|
if err != nil {
|
|
return
|
|
}
|
|
fsEntity.Name = newName
|
|
if err = os.Rename(filepath.Join(filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs"), path, "__files__", currentName), filepath.Join(filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs"), path, "__files__", newName)); err != nil {
|
|
return
|
|
}
|
|
if err = zfh.DB.SetFSEntity(path, currentName, fsEntity); err != nil {
|
|
return
|
|
}
|
|
for member := range fsEntity.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(RENAME_FILE_DONE, "node", member, map[string]interface{}{
|
|
"path": filepath.Join(path, newName),
|
|
"folderId": newName,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) UpdatePermissions(path, name, userId string, newPermission *FSEntityAccessRights) (err error) {
|
|
var updatePermission func(string, string) error
|
|
updatePermission = func(path, name string) (err error) {
|
|
fsEntity, err := zfh.DB.GetFSEntity(path, name)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if fsEntity.Folder {
|
|
splittedPath := append(filepath.SplitList(path), name)
|
|
childrens, _, err := zfh.DB.ListZoneFSEntity(filepath.Join(splittedPath...), userId, 0, 100)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
go func() {
|
|
for _, children := range childrens {
|
|
if children.Type == PARENT {
|
|
if err = updatePermission(filepath.Join(splittedPath...), children.Name); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
fsEntity.Members[userId] = newPermission
|
|
if err = zfh.DB.SetFSEntity(path, name, fsEntity); err != nil {
|
|
return
|
|
}
|
|
for member := range fsEntity.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(UPDATE_PERMISSIONS_DONE, "node", member, map[string]interface{}{
|
|
"path": filepath.Join(path, name),
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
err = updatePermission(path, name)
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) DeleteFolder(path, name string) (err error) {
|
|
fsEntity, err := zfh.DB.GetFSEntity(path, name)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if err = zfh.DB.DeleteFolder(path, name); err != nil {
|
|
return
|
|
}
|
|
for member := range fsEntity.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(DELETE_FOLDER_DONE, "node", member, map[string]interface{}{
|
|
"path": filepath.Join(path, name),
|
|
"folderId": name,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) DeleteFile(path, name string) (err error) {
|
|
fsEntity, err := zfh.DB.GetFSEntity(path, name)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if err = zfh.DB.DeleteFile(path, name); err != nil {
|
|
return
|
|
}
|
|
for member := range fsEntity.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(DELETE_FOLDER_DONE, "node", member, map[string]interface{}{
|
|
"path": filepath.Join(path, name),
|
|
"folderId": name,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) CopyFile(src, dst string, init bool, fsEntity *ZoneFSEntity) (err error) {
|
|
var srcfd *os.File
|
|
var dstfd *os.File
|
|
var srcinfo os.FileInfo
|
|
var srcPath string
|
|
var dstPath string
|
|
if init {
|
|
srcPath = filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs", filepath.Dir(src), "__files__", filepath.Base(src))
|
|
dstPath = filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs", filepath.Dir(dst), "__files__", filepath.Base(dst))
|
|
} else {
|
|
srcPath = filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs", src)
|
|
dstPath = filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs", dst)
|
|
}
|
|
if err = os.MkdirAll(filepath.Dir(dstPath), 0700); err != nil && !os.IsExist(err) {
|
|
return
|
|
}
|
|
if srcfd, err = os.Open(srcPath); err != nil {
|
|
return
|
|
}
|
|
defer srcfd.Close()
|
|
if dstfd, err = os.Create(dstPath); err != nil {
|
|
return
|
|
}
|
|
defer dstfd.Close()
|
|
if _, err = io.Copy(dstfd, srcfd); err != nil {
|
|
return
|
|
}
|
|
if srcinfo, err = os.Stat(srcPath); err != nil {
|
|
return
|
|
}
|
|
if err = os.Chmod(dstPath, srcinfo.Mode()); err != nil {
|
|
return
|
|
}
|
|
if init {
|
|
err = zfh.DB.AddNewFSEntity(filepath.Dir(dst), fsEntity)
|
|
for member := range fsEntity.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(COPY_FILE_DONE, "node", member, map[string]interface{}{
|
|
"path": dst,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) CopyDir(src, dst string, init bool, fsEntity *ZoneFSEntity) (err error) {
|
|
var fds []os.FileInfo
|
|
var srcinfo os.FileInfo
|
|
srcPath := filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs", src)
|
|
dstPath := filepath.Join(dataPath, "data", "zones", zfh.ZoneId, "fs", dst)
|
|
if srcinfo, err = os.Stat(srcPath); err != nil {
|
|
return
|
|
}
|
|
if init {
|
|
logger.Println("---------------------adding new fs entity---------------------")
|
|
if err = zfh.DB.AddNewFSEntity(filepath.Dir(dst), fsEntity); err != nil {
|
|
return
|
|
}
|
|
} else {
|
|
if err = os.MkdirAll(dstPath, srcinfo.Mode()); err != nil {
|
|
return
|
|
}
|
|
}
|
|
if fds, err = ioutil.ReadDir(srcPath); err != nil {
|
|
return
|
|
}
|
|
for _, fd := range fds {
|
|
srcfp := path.Join(src, fd.Name())
|
|
dstfp := path.Join(dst, fd.Name())
|
|
if fd.IsDir() {
|
|
if err = zfh.CopyDir(srcfp, dstfp, false, nil); err != nil {
|
|
logger.Println(err)
|
|
}
|
|
} else {
|
|
if err = zfh.CopyFile(srcfp, dstfp, false, nil); err != nil {
|
|
logger.Println(err)
|
|
}
|
|
}
|
|
}
|
|
if fsEntity != nil {
|
|
for member := range fsEntity.Members {
|
|
done, errCh := zfh.sendDataChannelMessage(COPY_FOLDER_DONE, "node", member, map[string]interface{}{
|
|
"path": dst,
|
|
})
|
|
select {
|
|
case <-done:
|
|
case sendErr := <-errCh:
|
|
logger.Println(sendErr)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) CutFolder(id, path, dstPath string, init bool, fsEntity *ZoneFSEntity) (err error) {
|
|
if err = zfh.CopyDir(path, dstPath, init, fsEntity); err != nil {
|
|
return
|
|
}
|
|
err = zfh.DeleteFolder(filepath.Dir(path), filepath.Base(path))
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) CutFile(id, path, dstPath string, init bool, fsEntity *ZoneFSEntity) (err error) {
|
|
if err = zfh.CopyFile(path, dstPath, init, fsEntity); err != nil {
|
|
return
|
|
}
|
|
err = zfh.DeleteFile(filepath.Dir(path), filepath.Base(path))
|
|
return
|
|
}
|
|
|
|
// func (zfh *ZoneFileHandler[T]) ConnectToFSInstance(channelId string, userId string, sdp string) (err error) {
|
|
// err = atomicallyExecute(zfh.FSInstanceFlag, func() (err error) {
|
|
// d, e := zfh.FSInstance.HandleOffer(context.Background(), channelId, userId, sdp, zfh.HostId, zfh.sendDataChannelMessage, zfh.signalCandidate)
|
|
// select {
|
|
// case <-d:
|
|
// case err = <-e:
|
|
// }
|
|
// return
|
|
// })
|
|
// return
|
|
// }
|
|
|
|
// func (zfh *ZoneFileHandler[T]) LeaveFSInstance(
|
|
// userId string) (err error) {
|
|
// err = atomicallyExecute(zfh.FSInstanceFlag, func() (err error) {
|
|
// zfh.FSInstance.HandleLeavingMember(userId)
|
|
// return
|
|
// })
|
|
// return
|
|
// }
|
|
|
|
func (zfh *ZoneFileHandler[T]) SetPublicRootFolders(user string) (err error) {
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) fileUpload(chatId string, filename string, userId string, dc *DataChannel) {
|
|
var writePipe chan<- []byte
|
|
var done bool
|
|
uploadDone := func() {
|
|
if writePipe != nil {
|
|
close(writePipe)
|
|
writePipe = nil
|
|
}
|
|
done = true
|
|
}
|
|
dc.DataChannel.OnError(func(err error) {
|
|
logger.Println(err)
|
|
logger.Println("abort...")
|
|
if !done {
|
|
uploadDone()
|
|
}
|
|
if fufErr := zfh.FSInstance.FileUploadFailed(chatId, filename, userId); fufErr != nil {
|
|
logger.Println(fufErr)
|
|
}
|
|
})
|
|
dc.DataChannel.OnClose(func() {
|
|
if done {
|
|
logger.Println("closing gracefully...")
|
|
} else {
|
|
logger.Println("abort...")
|
|
uploadDone()
|
|
if fufErr := zfh.FSInstance.FileUploadFailed(chatId, filename, userId); fufErr != nil {
|
|
logger.Println(fufErr)
|
|
}
|
|
}
|
|
})
|
|
dc.DataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
|
|
if msg.IsString {
|
|
if string(msg.Data) == "init_upload" {
|
|
logger.Println("init upload....")
|
|
var initErr error
|
|
if writePipe, initErr = zfh.FSInstance.SetupFileUpload(chatId, filename, userId, dc.DataChannel); initErr != nil {
|
|
_ = dc.DataChannel.SendText("abort")
|
|
_ = dc.DataChannel.Close()
|
|
return
|
|
}
|
|
logger.Println("upload ready !")
|
|
_ = dc.DataChannel.SendText("upload_ready")
|
|
} else if string(msg.Data) == "upload_done" {
|
|
uploadDone()
|
|
}
|
|
} else {
|
|
writePipe <- msg.Data
|
|
}
|
|
})
|
|
dc.DataChannel.OnOpen(func() {
|
|
_ = dc.DataChannel.SendText("channel_ready")
|
|
})
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) fileDownload(chatId string, filename string, userId string, dc *DataChannel) {
|
|
var done bool
|
|
dc.DataChannel.OnError(func(err error) {
|
|
if !done {
|
|
logger.Println("abort...")
|
|
if fdf := zfh.FSInstance.FileDownloadFailed(chatId, filename, userId); fdf != nil {
|
|
logger.Println(fdf)
|
|
}
|
|
}
|
|
})
|
|
dc.DataChannel.OnClose(func() {
|
|
if !done {
|
|
logger.Println("abort...")
|
|
if fdf := zfh.FSInstance.FileDownloadFailed(chatId, filename, userId); fdf != nil {
|
|
logger.Println(fdf)
|
|
}
|
|
}
|
|
})
|
|
dc.DataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
|
|
if msg.IsString {
|
|
if string(msg.Data) == "init_download" {
|
|
logger.Println("init download....")
|
|
var initErr error
|
|
if initErr = zfh.FSInstance.SetupFileDownload(chatId, filename, userId, dc.DataChannel); initErr != nil {
|
|
_ = dc.DataChannel.SendText("abort")
|
|
_ = dc.DataChannel.Close()
|
|
return
|
|
}
|
|
logger.Println("download started !")
|
|
} else if string(msg.Data) == "download_done" {
|
|
done = true
|
|
}
|
|
}
|
|
})
|
|
dc.DataChannel.OnOpen(func() {
|
|
_ = dc.DataChannel.SendText("channel_ready")
|
|
})
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) handleDataChannel(ctx context.Context, dc *DataChannel) (catched bool) {
|
|
var label string
|
|
_ = atomicallyExecute(dc.l, func() (err error) {
|
|
label = dc.DataChannel.Label()
|
|
return
|
|
})
|
|
if strings.Contains(label, "file_upload") {
|
|
command := strings.Split(label, "|")
|
|
if len(command) == 4 {
|
|
catched = true
|
|
go zfh.fileUpload(command[1], command[2], command[3], dc)
|
|
}
|
|
logger.Println(command)
|
|
} else if strings.Contains(label, "file_download") {
|
|
command := strings.Split(label, "|")
|
|
catched = true
|
|
go zfh.fileDownload(command[1], command[2], command[3], dc)
|
|
logger.Println(command)
|
|
} else if strings.Contains(label, "file_data") {
|
|
command := strings.Split(label, "|")
|
|
catched = true
|
|
_ = atomicallyExecute(zfh.FileDataChannelsFlag, func() (err error) {
|
|
zfh.FileDataChannels[command[1]] = dc
|
|
return
|
|
})
|
|
dc.DataChannel.OnClose(func() {
|
|
fmt.Println("closing gratefully fs dc...")
|
|
_ = atomicallyExecute(zfh.FileDataChannelsFlag, func() (err error) {
|
|
delete(zfh.FileDataChannels, command[1])
|
|
return
|
|
})
|
|
})
|
|
dc.DataChannel.OnError(func(err error) {
|
|
fmt.Println("error in fs dc...")
|
|
_ = atomicallyExecute(zfh.FileDataChannelsFlag, func() (err error) {
|
|
delete(zfh.FileDataChannels, command[1])
|
|
return
|
|
})
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zfh *ZoneFileHandler[T]) handleZoneRequest(c context.Context, req *ZoneRequest) (err error) {
|
|
switch req.ReqType {
|
|
case string(REMOVED_ZONE_AUTHORIZED_MEMBER):
|
|
if err = VerifyFieldsString(req.Payload, "userId"); err != nil {
|
|
return
|
|
}
|
|
var index int
|
|
var found bool
|
|
for i, m := range zfh.ZoneMembersId {
|
|
if m == req.Payload["userId"].(string) {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
err = fmt.Errorf("no such user in zone")
|
|
return
|
|
}
|
|
zfh.ZoneMembersId = append(zfh.ZoneMembersId[:index], zfh.ZoneMembersId[index+1:]...)
|
|
err = zfh.DeleteFolder("", req.Payload["userId"].(string))
|
|
case string(NEW_AUTHORIZED_ZONE_MEMBER):
|
|
if err = VerifyFieldsString(req.Payload, "userId"); err != nil {
|
|
return
|
|
}
|
|
var contain bool
|
|
for _, m := range zfh.ZoneMembersId {
|
|
if m == req.Payload["userId"].(string) {
|
|
contain = true
|
|
break
|
|
}
|
|
}
|
|
if !contain {
|
|
zfh.ZoneMembersId = append(zfh.ZoneMembersId, req.Payload["userId"].(string))
|
|
}
|
|
err = zfh.DB.AddNewFSEntity("", &ZoneFSEntity{
|
|
Name: req.Payload["userId"].(string),
|
|
Owner: req.Payload["userId"].(string),
|
|
Type: PRIVATE,
|
|
Folder: true,
|
|
ModTime: time.Now().Format(time.RFC3339),
|
|
CreationTime: time.Now().Format(time.RFC3339),
|
|
Size: 0,
|
|
Members: map[string]*FSEntityAccessRights{
|
|
req.Payload["userId"].(string): {
|
|
Read: true,
|
|
Write: true,
|
|
Download: true,
|
|
Rename: true,
|
|
},
|
|
},
|
|
})
|
|
case LEAVE_ZONE:
|
|
logger.Println("*-----------------handling leaving zone---------------*")
|
|
if err = VerifyFieldsString(req.Payload, "userId"); err != nil {
|
|
return
|
|
}
|
|
//err = zfh.LeaveFSInstance(req.Payload["userId"].(string))
|
|
case ZONE_UPLOAD_FILE_DONE:
|
|
if err = VerifyFieldsBool(req.Payload, "failed"); err != nil {
|
|
return
|
|
}
|
|
if err = VerifyFieldsString(req.Payload, "path", "userId", "fileName", "type"); err != nil {
|
|
return
|
|
}
|
|
if err = VerifyFieldsFloat64(req.Payload, "size"); err != nil {
|
|
return
|
|
}
|
|
if req.Payload["failed"].(bool) {
|
|
logger.Println(zfh.FSInstance.FileUploadFailed(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string)))
|
|
} else {
|
|
defer func() {
|
|
//logger.Println(zfh.FSInstance.FileUploadDone(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string)))
|
|
}()
|
|
err = zfh.CreateFile(req.Payload["path"].(string), req.Payload["fileName"].(string), &ZoneFSEntity{
|
|
Name: req.Payload["fileName"].(string),
|
|
Owner: req.Payload["userId"].(string),
|
|
Type: req.Payload["type"].(string),
|
|
Size: uint64(req.Payload["size"].(float64)),
|
|
ModTime: time.Now().Format(time.RFC3339),
|
|
CreationTime: time.Now().Format(time.RFC3339),
|
|
Folder: false,
|
|
Members: map[string]*FSEntityAccessRights{
|
|
req.Payload["userId"].(string): {
|
|
Read: true,
|
|
Write: true,
|
|
Download: true,
|
|
Rename: true,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
// case ZONE_UPLOAD_FILE:
|
|
// if err = verifyFieldsString(req.Payload, "path", "userId", "fileName"); err != nil {
|
|
// return
|
|
// }
|
|
// err = zfh.FSInstance.SetupFileUpload(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string))
|
|
// case ZONE_DOWNLOAD_FILE:
|
|
// if err = verifyFieldsString(req.Payload, "path", "userId", "fileName"); err != nil {
|
|
// return
|
|
// }
|
|
// err = zfh.FSInstance.SetupFileDownload(req.Payload["path"].(string), req.Payload["fileName"].(string), req.Payload["userId"].(string))
|
|
case GET_FS_ENTITIES:
|
|
logger.Println("getting files entities")
|
|
if err = VerifyFieldsString(req.Payload, "path", "userId", "section"); err != nil {
|
|
return
|
|
}
|
|
var backward bool
|
|
if err = VerifyFieldsBool(req.Payload, "backward"); err == nil {
|
|
backward = req.Payload["backward"].(bool)
|
|
}
|
|
if err = VerifyFieldsFloat64(req.Payload, "lastIndex", "limit"); err != nil {
|
|
return
|
|
}
|
|
err = zfh.GetFSEntities(req.Payload["userId"].(string), req.Payload["section"].(string), req.Payload["path"].(string), 0, 100, backward)
|
|
case CREATE_FOLDER:
|
|
logger.Println("creating folder")
|
|
if err = VerifyFieldsString(req.Payload, "path"); err != nil {
|
|
return
|
|
}
|
|
if _, ok := req.Payload["config"]; !ok {
|
|
err = fmt.Errorf("no field config in request payload")
|
|
return
|
|
}
|
|
bs, jsonErr := json.Marshal(req.Payload["config"])
|
|
if jsonErr != nil {
|
|
return jsonErr
|
|
}
|
|
var config ZoneFSEntity
|
|
if err = json.Unmarshal(bs, &config); err != nil {
|
|
err = fmt.Errorf("the config payload dont match ZoneFSEntity struct pattern : %v", err)
|
|
return
|
|
}
|
|
err = zfh.CreateFolder(req.Payload["path"].(string), &config)
|
|
case RENAME_FOLDER:
|
|
if err = VerifyFieldsString(req.Payload, "path", "name", "newName"); err != nil {
|
|
return
|
|
}
|
|
err = zfh.RenameFolder(req.Payload["path"].(string), req.Payload["name"].(string), req.Payload["newName"].(string))
|
|
case RENAME_FILE:
|
|
if err = VerifyFieldsString(req.Payload, "path", "name", "newName"); err != nil {
|
|
return
|
|
}
|
|
err = zfh.RenameFile(req.Payload["path"].(string), req.Payload["name"].(string), req.Payload["newName"].(string))
|
|
case COPY_FOLDER:
|
|
if err = VerifyFieldsString(req.Payload, "userId", "path", "dstPath"); err != nil {
|
|
return
|
|
}
|
|
if _, ok := req.Payload["config"]; !ok {
|
|
err = fmt.Errorf("no field config in request payload")
|
|
return
|
|
}
|
|
bs, jsonErr := json.Marshal(req.Payload["config"])
|
|
if jsonErr != nil {
|
|
return jsonErr
|
|
}
|
|
var config ZoneFSEntity
|
|
if err = json.Unmarshal(bs, &config); err != nil {
|
|
err = fmt.Errorf("the config payload dont match ZoneFSEntity struct pattern : %v", err)
|
|
return
|
|
}
|
|
go func() {
|
|
err = zfh.CopyDir(req.Payload["path"].(string), req.Payload["dstPath"].(string), true, &config)
|
|
logger.Println(err)
|
|
}()
|
|
case COPY_FILE:
|
|
if err = VerifyFieldsString(req.Payload, "userId", "path", "dstPath"); err != nil {
|
|
return
|
|
}
|
|
if _, ok := req.Payload["config"]; !ok {
|
|
err = fmt.Errorf("no field config in request payload")
|
|
return
|
|
}
|
|
bs, jsonErr := json.Marshal(req.Payload["config"])
|
|
if jsonErr != nil {
|
|
return jsonErr
|
|
}
|
|
var config ZoneFSEntity
|
|
if err = json.Unmarshal(bs, &config); err != nil {
|
|
err = fmt.Errorf("the config payload dont match ZoneFSEntity struct pattern : %v", err)
|
|
return
|
|
}
|
|
go func() {
|
|
err = zfh.CopyFile(req.Payload["path"].(string), req.Payload["dstPath"].(string), true, &config)
|
|
logger.Println(err)
|
|
}()
|
|
case CUT_FOLDER:
|
|
if err = VerifyFieldsString(req.Payload, "userId", "path", "dstPath"); err != nil {
|
|
return
|
|
}
|
|
if _, ok := req.Payload["config"]; !ok {
|
|
err = fmt.Errorf("no field config in request payload")
|
|
return
|
|
}
|
|
bs, jsonErr := json.Marshal(req.Payload["config"])
|
|
if jsonErr != nil {
|
|
return jsonErr
|
|
}
|
|
var config ZoneFSEntity
|
|
if err = json.Unmarshal(bs, &config); err != nil {
|
|
err = fmt.Errorf("the config payload dont match ZoneFSEntity struct pattern : %v", err)
|
|
return
|
|
}
|
|
go func() {
|
|
err = zfh.CutFolder(req.Payload["userId"].(string), req.Payload["path"].(string), req.Payload["dstPath"].(string), true, &config)
|
|
logger.Println(err)
|
|
}()
|
|
case CUT_FILE:
|
|
if err = VerifyFieldsString(req.Payload, "userId", "path", "dstPath"); err != nil {
|
|
return
|
|
}
|
|
if _, ok := req.Payload["config"]; !ok {
|
|
err = fmt.Errorf("no field config in request payload")
|
|
return
|
|
}
|
|
bs, jsonErr := json.Marshal(req.Payload["config"])
|
|
if jsonErr != nil {
|
|
return jsonErr
|
|
}
|
|
var config ZoneFSEntity
|
|
if err = json.Unmarshal(bs, &config); err != nil {
|
|
err = fmt.Errorf("the config payload dont match ZoneFSEntity struct pattern : %v", err)
|
|
return
|
|
}
|
|
go func() {
|
|
err = zfh.CutFile(req.Payload["userId"].(string), req.Payload["path"].(string), req.Payload["dstPath"].(string), true, &config)
|
|
logger.Println(err)
|
|
}()
|
|
case UPDATE_PERMISSIONS:
|
|
if err = VerifyFieldsString(req.Payload, "path", "name", "userId"); err != nil {
|
|
return
|
|
}
|
|
if err = VerifyFieldsBool(req.Payload, "read", "write", "download", "rename"); err != nil {
|
|
return
|
|
}
|
|
fsAcessRights := &FSEntityAccessRights{
|
|
Read: req.Payload["read"].(bool),
|
|
Write: req.Payload["write"].(bool),
|
|
Download: req.Payload["download"].(bool),
|
|
Rename: req.Payload["rename"].(bool),
|
|
}
|
|
err = zfh.UpdatePermissions(req.Payload["path"].(string), req.Payload["name"].(string), req.Payload["userId"].(string), fsAcessRights)
|
|
case DELETE_FOLDER:
|
|
if err = VerifyFieldsString(req.Payload, "path", "name"); err != nil {
|
|
return
|
|
}
|
|
err = zfh.DeleteFolder(req.Payload["path"].(string), req.Payload["name"].(string))
|
|
case DELETE_FILE:
|
|
if err = VerifyFieldsString(req.Payload, "path", "name"); err != nil {
|
|
return
|
|
}
|
|
err = zfh.DeleteFile(req.Payload["path"].(string), req.Payload["name"].(string))
|
|
case ADD_FS_ENTITY_MEMBERS:
|
|
if err = VerifyFieldsString(req.Payload, "path", "userId", "folderName"); err != nil {
|
|
return
|
|
}
|
|
if err = VerifyFieldsSliceInterface(req.Payload, "members"); err != nil {
|
|
return
|
|
}
|
|
if err = VerifyFieldsBool(req.Payload, "read", "write", "download", "rename"); err != nil {
|
|
return
|
|
}
|
|
err = zfh.AddFolderMember(req.Payload["userId"].(string), req.Payload["path"].(string), req.Payload["folderName"].(string), req.Payload["members"].([]interface{}), req.Payload["read"].(bool), req.Payload["write"].(bool), req.Payload["download"].(bool), req.Payload["rename"].(bool))
|
|
case REMOVE_FS_ENTITY_MEMBERS:
|
|
if err = VerifyFieldsString(req.Payload, "path", "userId", "folderName"); err != nil {
|
|
return
|
|
}
|
|
if err = VerifyFieldsSliceInterface(req.Payload, "members"); err != nil {
|
|
return
|
|
}
|
|
err = zfh.RemoveFolderMember(req.Payload["userId"].(string), req.Payload["path"].(string), req.Payload["folderName"].(string), req.Payload["members"].([]interface{}))
|
|
// case string(ZONE_FS_WEBRTC_OFFER):
|
|
// if err = verifyFieldsString(req.Payload, "channelId", "userId", "sdp"); err != nil {
|
|
// return
|
|
// }
|
|
// err = zfh.ConnectToFSInstance(req.Payload["channelId"].(string), req.Payload["userId"].(string), req.Payload["sdp"].(string))
|
|
// case string(ZONE_FS_WEBRTC_COUNTER_OFFER):
|
|
// logger.Println("handling fs instance counter offer")
|
|
// if err = verifyFieldsString(req.Payload, "channelId", "userId"); err != nil {
|
|
// return
|
|
// }
|
|
// err = atomicallyExecute(zfh.FSInstanceFlag, func() (err error) {
|
|
// err = zfh.FSInstance.HandleCounterOffer(context.Background(), req.Payload["userId"].(string), zfh.sendDataChannelMessage)
|
|
// return
|
|
// })
|
|
// case string(ZONE_FS_WEBRTC_RENNEGOTIATION_OFFER):
|
|
// if err = verifyFieldsString(req.Payload, "channelId", "userId", "sdp"); err != nil {
|
|
// return
|
|
// }
|
|
// err = atomicallyExecute(zfh.FSInstanceFlag, func() (err error) {
|
|
// err = zfh.FSInstance.HandleRennegotiationOffer(req.Payload["userId"].(string), req.Payload["sdp"].(string), zfh.sendDataChannelMessage)
|
|
// return
|
|
// })
|
|
// case string(ZONE_FS_WEBRTC_RENNEGOTIATION_ANSWER):
|
|
// if err = verifyFieldsString(req.Payload, "channelId", "userId", "sdp"); err != nil {
|
|
// return
|
|
// }
|
|
// err = atomicallyExecute(zfh.FSInstanceFlag, func() (err error) {
|
|
// err = zfh.FSInstance.HandleRennegotiationAnswer(req.Payload["userId"].(string), req.Payload["sdp"].(string))
|
|
// return
|
|
// })
|
|
// case string(ZONE_FS_WEBRTC_CANDIDATE):
|
|
// logger.Println("handling fs instance webrtc candidate")
|
|
// logger.Println(req.Payload)
|
|
// if err = verifyFieldsString(req.Payload, FROM, "candidate", "sdpMLineIndex", "sdpMid", "channelId", "userId"); err != nil {
|
|
// return
|
|
// }
|
|
// logger.Println(req.Payload)
|
|
// i, convErr := strconv.Atoi(req.Payload["sdpMLineIndex"].(string))
|
|
// if convErr != nil {
|
|
// return convErr
|
|
// }
|
|
// SDPMLineIndex := uint16(i)
|
|
// sdpMid := req.Payload["sdpMid"].(string)
|
|
// logger.Println(sdpMid, SDPMLineIndex)
|
|
// err = atomicallyExecute(zfh.FSInstanceFlag, func() (err error) {
|
|
// err = zfh.FSInstance.AddCandidate(&webrtc.ICECandidateInit{
|
|
// Candidate: req.Payload["candidate"].(string),
|
|
// SDPMid: &sdpMid,
|
|
// SDPMLineIndex: &SDPMLineIndex,
|
|
// }, req.Payload["userId"].(string))
|
|
// return
|
|
// })
|
|
default:
|
|
logger.Println("got your request in zone file handler", req)
|
|
return
|
|
}
|
|
return
|
|
}
|