# `toccofs` - FUSE-Based Network FS for Tocco DMS

## Introduction

A network filesystem allowing to mount [Tocco DMS][] locally via
[Tocco's REST API][] and accessing it via filesystem. It's
implemented using [FUSE][] (Filesystem in Userspace).

This is a personal project, this software is not provided by [Tocco AG][],
although it interfaces with their software, Tocco. This is a fun project and is
unlikely to be maintained long-term. More features may get added, or bugs
fixed but don't count on it.

## Prerequisites

* An operating system with FUSE support (e.g. Linux or FreeBSD).
* An [API key][]. (You may not have permissions to create one.)

## Quick Guide

```
toccofs mount --user-name <user_name> --api-key-file <path_to_key_file> <hostname> <mount_dir>
```

Example:

```
mkdir mnt  # empty folder
toccofs --user-name pgerber --api-key-file ~/tocco-api-key master.tocco.ch mnt/
```

Then access the FS:

```
ls -lh mnt/
drwxr-xr-x 1 root root 0 Apr 16  2024 Documents
drwxr-xr-x 1 root root 0 Apr 16  2024 Internal
drwxr-xr-x 1 root root 0 Apr 16  2024 Temp
...
```

And ultimately, unmount it again:

```
fusermount -u mnt/
```

## Options

### `--user-name` and `--api-key-file`

Use it to make sure you have access to restricted files and folders. If omitted,
publicly visible files and folders will still show up.

### `--business-unit`

If you have access to multiple [Business Units], this allows to restrict what folders
are visible. Use this when, across Business Units, root folder names (AKA domain names)
aren't unique and multiple folders with the same name appear.

### `RUST_LOG=` env. var.

Enable *debug* or *trace* logging:

```
RUST_LOG=debug toccofs mount ...
```

See also [env_logger documention][].

Default is equal to `RUST_LOG=toccofs=info`.

### Extended Attributes (xattr)

Extended attributes can be used to retrieve the corresponding URLs on the API
and admin interface.

```
$ getfattr -d path/to/file
# file: path/to/file
user.admin_url="https://master.tocco.ch/tocco/docs/doc/22723/detail"
user.entity_api_url="https://master.tocco.ch/nice2/rest/entities/2.0/Resource/22723"
```

or:

```
$ xattr -l path/to/file
user.admin_url: https://master.tocco.ch/tocco/docs/doc/22723/detail
user.entity_api_url: https://master.tocco.ch/nice2/rest/entities/2.0/Resource/22723
```

## File Names (vs Tocco Labels)

Some file / folder / domain names (AKA labels) used by Tocco cannot be used in a
filesystem. They are simply not valid file names. Such names are encoded in a
reversible manner to allow accessing all files in Tocco via toccofs.

The most notable encoding is the one of `'/'`, a character not allowed in
a file name. This character is encoded as `'⫽'`.

## Features

### Supported

* list folders (readdir)
* get file attributes (fstat)
* read files (read)
* rename and move (rename)
* remove files and directories (unlink, rmdir)
* create directories / domains (mkdir)

### Unsupported

* sync files (fsync)
* write files (write)

## Caveats

* Performance

  Very little has been done to optimize performance. In particular, reads will
  be very slow. All downloads are currently synchronous with no other read-ahead
  than that provided by the OS.

* Missing files:

  Some files or folders may not show up because they do not have a valid name. They
  may contains slashes or be the reserved names "." or "..".

* Lost and found:

  In Tocco, it's possible for a folder/file to be visible but not it's parent directory.
  Such orphaned entries are visible in the hidden *.lost+found* directory:

  ```
  ls -lha mnt/
  ...
  drwxr-xr-x 1 root root   0 Jan  1  1970 .lost+found
  ...
  ```

  Names will have their ID prefixed to avoid name collisions.


[Business Units]: https://latest.docs.tocco.ch/Grundinstallation/core_beschreibung_konfiggb.html
[API key]: https://latest.docs.tocco.ch/Integrator/integrator_beschreibung_login_rest.html
[FUSE]: https://github.com/libfuse/libfuse
[Tocco AG]: https://www.tocco.ch
[Tocco DMS]: https://latest.docs.tocco.ch/Dokument/headingdokument.html
[Tocco's REST API]: https://master.tocco.ch/nice2/swagger
[env_logger documention]: https://docs.rs/env_logger/latest/env_logger/index.html
