fileshare

package
v0.0.0-...-851e5e8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2024 License: GPL-3.0 Imports: 27 Imported by: 0

Documentation

Overview

Package fileshare provides gRPC interface for the fileshare functionality.

Index

Constants

View Source
const (
	DirDepthLimit     = 5
	TransferFileLimit = 1000
)

Variables

View Source
var (
	ErrTransferNotFound               = errors.New("transfer not found")
	ErrFileNotFound                   = errors.New("file not found")
	ErrTransferAlreadyAccepted        = errors.New("can't accept already accepted transfer")
	ErrTransferAcceptOutgoing         = errors.New("can't accept outgoing transfer")
	ErrSizeLimitExceeded              = errors.New("provided size limit exceeded")
	ErrAcceptDirNotFound              = errors.New("accept directory not found")
	ErrAcceptDirIsASymlink            = errors.New("accept directory is a symlink")
	ErrAcceptDirIsNotADirectory       = errors.New("accept directory is not a directory")
	ErrNoPermissionsToAcceptDirectory = errors.New("no permissions to accept directory")
	ErrNotificationsAlreadyEnabled    = errors.New("notifications already enabled")
	ErrNotificationsAlreadyDisabled   = errors.New("notifications already disabled")
	ErrTransferCanceledByPeer         = errors.New("transfer has been canceled by peer")
	ErrTransferCanceledByUs           = errors.New("transfer has been canceled by us")
)

Handleable errors

View Source
var (
	IncomingStatus = map[pb.Status]string{
		pb.Status_REQUESTED:            "waiting for download",
		pb.Status_ONGOING:              "downloading",
		pb.Status_SUCCESS:              "completed",
		pb.Status_INTERRUPTED:          "interrupted",
		pb.Status_FINISHED_WITH_ERRORS: "completed with errors",
		pb.Status_ACCEPT_FAILURE:       "accepted with errors",
		pb.Status_CANCELED:             "canceled",
		pb.Status_CANCELED_BY_PEER:     "canceled by peer",
		pb.Status_PENDING:              "pending",
	}
	OutgoingStatus = map[pb.Status]string{
		pb.Status_REQUESTED:            "request sent",
		pb.Status_ONGOING:              "uploading",
		pb.Status_SUCCESS:              "completed",
		pb.Status_INTERRUPTED:          "interrupted",
		pb.Status_FINISHED_WITH_ERRORS: "completed with errors",
		pb.Status_ACCEPT_FAILURE:       "accepted with errors",
		pb.Status_CANCELED:             "canceled",
		pb.Status_CANCELED_BY_PEER:     "canceled by peer",
		pb.Status_FILE_REJECTED:        "the receiver has declined the file transfer",
		pb.Status_PENDING:              "pending",
	}
	FileStatus = map[pb.Status]string{
		pb.Status_SUCCESS:                  "completed",
		pb.Status_CANCELED:                 "canceled",
		pb.Status_INTERRUPTED:              "interrupted",
		pb.Status_PENDING:                  "pending",
		pb.Status_BAD_PATH:                 "the download path is not valid",
		pb.Status_BAD_FILE:                 "the file is no longer found",
		pb.Status_TRANSPORT:                "transport problem",
		pb.Status_BAD_STATUS:               "bad status",
		pb.Status_SERVICE_STOP:             "service not active",
		pb.Status_BAD_TRANSFER:             "bad transfer",
		pb.Status_BAD_TRANSFER_STATE:       "bad transfer state",
		pb.Status_BAD_FILE_ID:              "bad file id",
		pb.Status_BAD_SYSTEM_TIME:          "bad system time",
		pb.Status_TRUNCATED_FILE:           "truncated file",
		pb.Status_EVENT_SEND:               "internal error",
		pb.Status_BAD_UUID:                 "internal error",
		pb.Status_CHANNEL_CLOSED:           "internal error",
		pb.Status_IO:                       "io error",
		pb.Status_DATA_SEND:                "data send error",
		pb.Status_DIRECTORY_NOT_EXPECTED:   "directory not expected",
		pb.Status_EMPTY_TRANSFER:           "empty transfer",
		pb.Status_TRANSFER_CLOSED_BY_PEER:  "transfer closed by peer",
		pb.Status_TRANSFER_LIMITS_EXCEEDED: "directory depth or breadth limits are exceeded",
		pb.Status_MISMATCHED_SIZE:          "the file has been modified",
		pb.Status_UNEXPECTED_DATA:          "the file has been modified",
		pb.Status_INVALID_ARGUMENT:         "internal error",
		pb.Status_TRANSFER_TIMEOUT:         "transfer timeout",
		pb.Status_WS_SERVER:                "waiting for peer to come online",
		pb.Status_WS_CLIENT:                "waiting for peer to come online",
		pb.Status_FILE_MODIFIED:            "the file has been modified",
		pb.Status_FILENAME_TOO_LONG:        "filename too long",
		pb.Status_AUTHENTICATION_FAILED:    "authentication failed",
		pb.Status_FILE_CHECKSUM_MISMATCH:   "the file is corrupted",
	}
	IncomingFileStatus = map[pb.Status]string{
		pb.Status_SUCCESS:              "downloaded",
		pb.Status_CANCELED:             "canceled",
		pb.Status_REQUESTED:            "waiting for download",
		pb.Status_ONGOING:              "downloading",
		pb.Status_FINISHED_WITH_ERRORS: "downloaded with errors",
		pb.Status_ACCEPT_FAILURE:       "accepted with errors",
	}
	OutgoingFileStatus = map[pb.Status]string{
		pb.Status_SUCCESS:              "uploaded",
		pb.Status_CANCELED:             "canceled",
		pb.Status_REQUESTED:            "request sent",
		pb.Status_ONGOING:              "uploading",
		pb.Status_FINISHED_WITH_ERRORS: "uploaded with errors",
		pb.Status_ACCEPT_FAILURE:       "accepted with errors",
	}
)

Functions

func FindTransferFileByPath

func FindTransferFileByPath(tr *pb.Transfer, filePath string) *pb.File

func ForAllFiles

func ForAllFiles(files []*pb.File, op func(*pb.File))

ForAllFiles executes op for all files in files

func GetDefaultDownloadDirectory

func GetDefaultDownloadDirectory() (string, error)

GetDefaultDownloadDirectory returns users Downloads directory or an error if it doesn't exist

func GetSelfPeer

func GetSelfPeer(meshClient meshpb.MeshnetClient) (*meshpb.Peer, error)

GetSelfPeer from meshnet client

func GetTransferFileStatus

func GetTransferFileStatus(file *pb.File, in bool) (status string)

GetTransferFileStatus file status to human readable string

func GetTransferFilesByPathPrefix

func GetTransferFilesByPathPrefix(tr *pb.Transfer, filePath string) []*pb.File

Gets all files with the given path prefix (returns all children of directory)

func GetTransferStatus

func GetTransferStatus(tr *pb.Transfer) string

GetTransferStatus translate transfer status into human readable form

func LibdropTransferToInternalTransfer

func LibdropTransferToInternalTransfer(in LibdropTransfer) *pb.Transfer

LibdropTransferToInternalTransfer converts libdrop transfer to our own representation. We have to wait for version 4.0.0(or other major version) to get rid of this, because it would cause breaking changes.

func SetTransferAllFileStatus

func SetTransferAllFileStatus(tr *pb.Transfer, status pb.Status)

SetTransferAllFileStatus reset all files to status

Types

type Action

type Action struct {
	Key    string
	Action string
}

Action represents an action available to the user when notification is displayed

type DbusNotifier

type DbusNotifier struct {
	// contains filtered or unexported fields
}

DbusNotifier wraps github.com/esiqveland/notify notifier implementation

func (*DbusNotifier) Close

func (n *DbusNotifier) Close() error

Close dbus connection. Thread safe.

func (*DbusNotifier) SendNotification

func (n *DbusNotifier) SendNotification(summary string, body string, actions []Action) (uint32, error)

SendNotification sends notification via dbus. Thread safe.

type EventManager

type EventManager struct {
	// contains filtered or unexported fields
}

EventManager is responsible for libdrop event handling. It keeps transfer state, distributes events to further subscribers, and uses Storage for transfer state persistence. Thread safe.

func NewEventManager

func NewEventManager(
	isProd bool,
	meshClient meshpb.MeshnetClient,
	osInfo OsInfo,
	filesystem Filesystem,
	defaultDownloadDir string) *EventManager

NewEventManager loads transfer state from storage, or creates empty state if loading fails.

func (*EventManager) AcceptTransfer

func (em *EventManager) AcceptTransfer(
	transferID string,
	path string,
	filePaths []string,
) (*pb.Transfer, error)

AcceptTransfer validates the transfer to ensure it can be accepted

func (*EventManager) CancelLiveTransfers

func (em *EventManager) CancelLiveTransfers()

CancelLiveTransfers cancels all ongoing transfers.

func (*EventManager) DisableNotifications

func (em *EventManager) DisableNotifications() error

func (*EventManager) EnableNotifications

func (em *EventManager) EnableNotifications(fileshare Fileshare) error

func (*EventManager) EventFunc

func (em *EventManager) EventFunc(eventJSON string)

EventFunc processes events and handles live transfer state. It should be passed directly to libdrop to be called on events.

func (*EventManager) GetTransfer

func (em *EventManager) GetTransfer(transferID string) (*pb.Transfer, error)

GetTransfer by ID.

func (*EventManager) GetTransfers

func (em *EventManager) GetTransfers() ([]*pb.Transfer, error)

GetTransfers is used for listing transfers. Returned transfers are sorted by date created from oldest to newest.

func (*EventManager) SetFileshare

func (em *EventManager) SetFileshare(fileshare Fileshare)

SetFileshare must be called before using event manager. Necessary because of circular dependency between event manager and libDrop.

func (*EventManager) SetStorage

func (em *EventManager) SetStorage(storage Storage)

SetStorage must be called before using event manager. Necessary because of circular dependency between event manager and libDrop.

func (*EventManager) Subscribe

func (em *EventManager) Subscribe(id string) <-chan TransferProgressInfo

Subscribe is used to track progress.

type Fileshare

type Fileshare interface {
	// Enable starts service listening at provided address
	Enable(listenAddress netip.Addr) error
	// Disable tears down fileshare service
	Disable() error
	// Send sends the provided file or dir to provided peer and returns transfer ID
	Send(peer netip.Addr, paths []string) (string, error)
	// Accept accepts provided files from provided request and starts download process
	Accept(transferID, dstPath string, fileID string) error
	// Cancel file transfer by ID.
	Cancel(transferID string) error
	// CancelFile id in a transfer
	CancelFile(transferID string, fileID string) error
	// GetTransfersSince provided time from fileshare implementation storage
	GetTransfersSince(t time.Time) ([]LibdropTransfer, error)
	// PurgeTransfersUntil provided time from fileshare implementation storage
	PurgeTransfersUntil(until time.Time) error
}

Fileshare defines a set of operations that any type that wants to act as a fileshare service must implement.

type Filesystem

type Filesystem interface {
	fs.StatFS
	fs.ReadDirFS
	Statfs(path string) (unix.Statfs_t, error)
	Lstat(path string) (fs.FileInfo, error)
}

Filesystem defines file operations used by fileshare

type LibdropFile

type LibdropFile struct {
	ID           string             `json:"file_id"`
	TransferID   string             `json:"transfer_id"`
	BasePath     string             `json:"base_path"`
	RelativePath string             `json:"relative_path"`
	TotalSize    uint64             `json:"bytes"`
	CreatedAt    uint64             `json:"created_at"`
	States       []LibdropFileState `json:"states"`
}

type LibdropFileState

type LibdropFileState struct {
	CreatedAt     uint64 `json:"created_at"`
	State         string `json:"state"`
	BytesSent     uint64 `json:"bytes_sent"`
	BytesReceived uint64 `json:"bytes_received"`
	BasePath      string `json:"base_dir"`
	FinalPath     string `json:"final_path"`
	StatusCode    int    `json:"status_code"`
}

type LibdropTransfer

type LibdropTransfer struct {
	ID        string                 `json:"id"`
	Peer      string                 `json:"peer_id"`
	CreatedAt int64                  `json:"created_at"`
	States    []LibdropTransferState `json:"states"`
	Direction string                 `json:"type"`
	Files     []LibdropFile          `json:"paths"`
}

LibdropTransfer as represented in libdrop storage

type LibdropTransferState

type LibdropTransferState struct {
	CreatedAt  uint64 `json:"created_at"`
	State      string `json:"state"`
	ByPeer     bool   `json:"by_peer"`
	StatusCode int    `json:"status_code"`
}

type LiveFile

type LiveFile struct {
	ID          string
	FullPath    string
	Size        uint64
	Transferred uint64
	Finished    bool
}

LiveFile is part of LiveTransfer

type LiveTransfer

type LiveTransfer struct {
	ID               string
	Direction        pb.Direction
	TotalSize        uint64
	TotalTransferred uint64
	Files            map[string]*LiveFile // Key is ID
}

LiveTransfer to track ongoing transfers live in app based on events

type NotificationManager

type NotificationManager struct {
	// contains filtered or unexported fields
}

NotificationManager is responsible for creating gui pop-up notifications for changes in transfer file status

func NewNotificationManager

func NewNotificationManager(fileshare Fileshare, eventManager *EventManager) (*NotificationManager, error)

NewNotificationManager creates a new notification

func (*NotificationManager) AcceptTransfer

func (nm *NotificationManager) AcceptTransfer(notificationID uint32)

AcceptTransfer associated with notificationID, generates notifications on failure

func (*NotificationManager) CancelTransfer

func (nm *NotificationManager) CancelTransfer(notificationID uint32)

CancelTransfer associated with notificationID, generates error notifiacation on failure

func (*NotificationManager) CloseNotification

func (nm *NotificationManager) CloseNotification(notificationID uint32)

CloseNotification cleans up any data associated with notificationID

func (*NotificationManager) Disable

func (nm *NotificationManager) Disable()

func (*NotificationManager) NotifyAutoacceptFailed

func (nm *NotificationManager) NotifyAutoacceptFailed(transferID string, peer string, reason error)

NotifyAutoacceptFailed creates a pop-up gui notification

func (*NotificationManager) NotifyFile

func (nm *NotificationManager) NotifyFile(filename string, direction pb.Direction, status pb.Status)

NotifyFile creates a pop-up gui notification, in case of incoming files, filename should be a full path (download path + filename), so that it can be opened by the user.

func (*NotificationManager) NotifyNewAutoacceptTransfer

func (nm *NotificationManager) NotifyNewAutoacceptTransfer(transferID string, peer string)

NotifyNewAutoacceptTransfer creates a pop-up gui notification

func (*NotificationManager) NotifyNewTransfer

func (nm *NotificationManager) NotifyNewTransfer(transferID string, peer string)

NotifyTransfer creates a pop-up gui notification

func (*NotificationManager) OpenFile

func (nm *NotificationManager) OpenFile(notificationID uint32)

OpenFile associated with notificationID

type Notifier

type Notifier interface {
	SendNotification(summary string, body string, actions []Action) (uint32, error)
	Close() error
}

Notifier is responsible for sending notifications to the user

type OsInfo

type OsInfo interface {
	CurrentUser() (*user.User, error)
	GetGroupIds(*user.User) ([]string, error)
}

type PubkeyProvider

type PubkeyProvider struct {
	// contains filtered or unexported fields
}

PubkeyProvider for libdrop

func NewPubkeyProvider

func NewPubkeyProvider(meshClient meshpb.MeshnetClient) *PubkeyProvider

NewPubkeyProvider must be used to create PubkeyProvider

func (*PubkeyProvider) PubkeyFunc

func (c *PubkeyProvider) PubkeyFunc(peerIP string) []byte

PubkeyFunc is called by libdrop on incoming requests to verify their validity

type Server

type Server struct {
	pb.UnimplementedFileshareServer
	// contains filtered or unexported fields
}

Server implements fileshare rpc receiver

func NewServer

func NewServer(
	fileshare Fileshare,
	eventManager *EventManager,
	meshClient meshpb.MeshnetClient,
	filesystem Filesystem,
	osInfo OsInfo,
	listChunkSize int,
	shutdownChan chan<- struct{},
) *Server

NewServer is a default constructor for a fileshare server

func (*Server) Accept

func (s *Server) Accept(req *pb.AcceptRequest, srv pb.Fileshare_AcceptServer) error

Accept rpc

func (*Server) Cancel

func (s *Server) Cancel(
	ctx context.Context,
	req *pb.CancelRequest,
) (*pb.Error, error)

Cancel rpc

func (*Server) CancelFile

func (s *Server) CancelFile(ctx context.Context, req *pb.CancelFileRequest) (*pb.Error, error)

CancelFile rpc

func (*Server) List

func (s *Server) List(_ *pb.Empty, srv pb.Fileshare_ListServer) error

List rpc

func (*Server) Ping

func (*Server) Ping(ctx context.Context, _ *pb.Empty) (*pb.Empty, error)

Ping rpc

func (*Server) PurgeTransfersUntil

func (s *Server) PurgeTransfersUntil(ctx context.Context, req *pb.PurgeTransfersUntilRequest) (*pb.Error, error)

func (*Server) Send

func (s *Server) Send(req *pb.SendRequest, srv pb.Fileshare_SendServer) error

Send rpc

func (*Server) SetNotifications

func (*Server) Stop

func (s *Server) Stop(ctx context.Context, _ *pb.Empty) (*pb.Empty, error)

Stop rpc

type StdFilesystem

type StdFilesystem struct {
	// contains filtered or unexported fields
}

StdFilesystem is a wrapper for golang std filesystem implementation

func NewStdFilesystem

func NewStdFilesystem(basepath string) StdFilesystem

NewStdFilesystem creates an StdFilesystem instance, basepath is the path prepended to all path arguments

func (StdFilesystem) Lstat

func (stdFs StdFilesystem) Lstat(path string) (fs.FileInfo, error)

Lstat a path

func (StdFilesystem) Open

func (stdFs StdFilesystem) Open(name string) (fs.File, error)

Open a file

func (StdFilesystem) ReadDir

func (stdFs StdFilesystem) ReadDir(path string) ([]fs.DirEntry, error)

ReadDir returns DirEntry for all of the files and directories in path

func (StdFilesystem) Stat

func (stdFs StdFilesystem) Stat(path string) (fs.FileInfo, error)

Stat a path

func (StdFilesystem) Statfs

func (stdFs StdFilesystem) Statfs(path string) (unix.Statfs_t, error)

Statfs returns info about filesystem

type StdOsInfo

type StdOsInfo struct{}

func (StdOsInfo) CurrentUser

func (StdOsInfo) CurrentUser() (*user.User, error)

func (StdOsInfo) GetGroupIds

func (StdOsInfo) GetGroupIds(user *user.User) ([]string, error)

type Storage

type Storage interface {
	Load() (map[string]*pb.Transfer, error)
	PurgeTransfersUntil(until time.Time) error
}

Storage is used for filesharing history persistence

type TransferProgressInfo

type TransferProgressInfo struct {
	TransferID  string
	Transferred uint32 // percent of transferred bytes
	Status      pb.Status
}

TransferProgressInfo info to report to the user

Directories

Path Synopsis
Package libdrop wraps libdrop fileshare implementation.
Package libdrop wraps libdrop fileshare implementation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL