diff --git a/src/caps/caps.go b/src/caps/caps.go
index 120aee103da9c7239c823d2850181bb67f462f98..e59ca2f3bc33e6f9ae15678d20a9a9829409b8f5 100644
--- a/src/caps/caps.go
+++ b/src/caps/caps.go
@@ -1,118 +1,118 @@
 package caps
 
 import (
-	"errors"
+    "errors"
 )
 
 type Capabilities map[string]int
 
 const (
-	CAP_USER_CREATE string   = "USER_CREATE"
-	CAP_USER_DESTROY         = "USER_DESTROY"
-	CAP_USER_SET_CAPS        = "USER_SET_CAPS"
-	CAP_USER_SET_PWD         = "USER_SET_PWD"
-	CAP_USER_LIST            = "USER_LIST"
+    CAP_USER_CREATE string   = "USER_CREATE"
+    CAP_USER_DESTROY         = "USER_DESTROY"
+    CAP_USER_SET_CAPS        = "USER_SET_CAPS"
+    CAP_USER_SET_PWD         = "USER_SET_PWD"
+    CAP_USER_LIST            = "USER_LIST"
 
-	CAP_VM_LIST              = "VM_LIST"
-	CAP_VM_LIST_ANY	         = "VM_LIST_ANY"
-	CAP_VM_START             = "VM_START"
-	CAP_VM_START_ANY         = "VM_START_ANY"
-	CAP_VM_STOP              = "VM_STOP"
-	CAP_VM_STOP_ANY          = "VM_STOP_ANY"
-	CAP_VM_REBOOT            = "VM_REBOOT"
-	CAP_VM_REBOOT_ANY        = "VM_REBOOT_ANY"
-	CAP_VM_CREATE            = "VM_CREATE"
-	CAP_VM_DESTROY           = "VM_DESTROY"
-	CAP_VM_DESTROY_ANY       = "VM_DESTROY_ANY"
-	CAP_VM_EDIT              = "VM_EDIT"
-	CAP_VM_EDIT_ANY          = "VM_EDIT_ANY"
-	CAP_VM_SET_ACCESS        = "VM_SET_ACCESS"
-	CAP_VM_READFS            = "VM_READFS"
-	CAP_VM_READFS_ANY        = "VM_READFS_ANY"
-	CAP_VM_WRITEFS           = "VM_WRITEFS"
-	CAP_VM_WRITEFS_ANY       = "VM_WRITEFS_ANY"
+    CAP_VM_LIST              = "VM_LIST"
+    CAP_VM_LIST_ANY          = "VM_LIST_ANY"
+    CAP_VM_START             = "VM_START"
+    CAP_VM_START_ANY         = "VM_START_ANY"
+    CAP_VM_STOP              = "VM_STOP"
+    CAP_VM_STOP_ANY          = "VM_STOP_ANY"
+    CAP_VM_REBOOT            = "VM_REBOOT"
+    CAP_VM_REBOOT_ANY        = "VM_REBOOT_ANY"
+    CAP_VM_CREATE            = "VM_CREATE"
+    CAP_VM_DESTROY           = "VM_DESTROY"
+    CAP_VM_DESTROY_ANY       = "VM_DESTROY_ANY"
+    CAP_VM_EDIT              = "VM_EDIT"
+    CAP_VM_EDIT_ANY          = "VM_EDIT_ANY"
+    CAP_VM_SET_ACCESS        = "VM_SET_ACCESS"
+    CAP_VM_READFS            = "VM_READFS"
+    CAP_VM_READFS_ANY        = "VM_READFS_ANY"
+    CAP_VM_WRITEFS           = "VM_WRITEFS"
+    CAP_VM_WRITEFS_ANY       = "VM_WRITEFS_ANY"
 
-	CAP_TPL_CREATE           = "TPL_CREATE"
-	CAP_TPL_EDIT             = "TPL_EDIT"
-	CAP_TPL_EDIT_ANY         = "TPL_EDIT_ANY"
-	CAP_TPL_LIST             = "TPL_LIST"
-	CAP_TPL_LIST_ANY         = "TPL_LIST_ANY"
-	CAP_TPL_DESTROY          = "TPL_DESTROY"
-	CAP_TPL_DESTROY_ANY      = "TPL_DESTROY_ANY"
-	CAP_TPL_READFS           = "TPL_READFS"
-	CAP_TPL_READFS_ANY       = "TPL_READFS_ANY"
+    CAP_TPL_CREATE           = "TPL_CREATE"
+    CAP_TPL_EDIT             = "TPL_EDIT"
+    CAP_TPL_EDIT_ANY         = "TPL_EDIT_ANY"
+    CAP_TPL_LIST             = "TPL_LIST"
+    CAP_TPL_LIST_ANY         = "TPL_LIST_ANY"
+    CAP_TPL_DESTROY          = "TPL_DESTROY"
+    CAP_TPL_DESTROY_ANY      = "TPL_DESTROY_ANY"
+    CAP_TPL_READFS           = "TPL_READFS"
+    CAP_TPL_READFS_ANY       = "TPL_READFS_ANY"
 )
 
 // Capabilities stored in the user config
 var userCaps = Capabilities {
-	CAP_USER_CREATE: 1,
-	CAP_USER_DESTROY: 1,
-	CAP_USER_SET_CAPS: 1,
-	CAP_USER_LIST: 1,
+    CAP_USER_CREATE: 1,
+    CAP_USER_DESTROY: 1,
+    CAP_USER_SET_CAPS: 1,
+    CAP_USER_LIST: 1,
 
-	CAP_VM_CREATE: 1,
-	CAP_VM_DESTROY_ANY: 1,
-	CAP_VM_EDIT_ANY: 1,
-	CAP_VM_START_ANY: 1,
-	CAP_VM_STOP_ANY: 1,
-	CAP_VM_REBOOT_ANY: 1,
-	CAP_VM_LIST_ANY: 1,
-	CAP_VM_SET_ACCESS: 1,
-	CAP_VM_READFS_ANY: 1,
-	CAP_VM_WRITEFS_ANY: 1,
+    CAP_VM_CREATE: 1,
+    CAP_VM_DESTROY_ANY: 1,
+    CAP_VM_EDIT_ANY: 1,
+    CAP_VM_START_ANY: 1,
+    CAP_VM_STOP_ANY: 1,
+    CAP_VM_REBOOT_ANY: 1,
+    CAP_VM_LIST_ANY: 1,
+    CAP_VM_SET_ACCESS: 1,
+    CAP_VM_READFS_ANY: 1,
+    CAP_VM_WRITEFS_ANY: 1,
 
-	CAP_TPL_CREATE: 1,
-	CAP_TPL_EDIT: 1,
-	CAP_TPL_EDIT_ANY: 1,
-	CAP_TPL_DESTROY: 1,
-	CAP_TPL_DESTROY_ANY: 1,
-	CAP_TPL_LIST: 1,
-	CAP_TPL_LIST_ANY: 1,
-	CAP_TPL_READFS: 1,
-	CAP_TPL_READFS_ANY: 1,
+    CAP_TPL_CREATE: 1,
+    CAP_TPL_EDIT: 1,
+    CAP_TPL_EDIT_ANY: 1,
+    CAP_TPL_DESTROY: 1,
+    CAP_TPL_DESTROY_ANY: 1,
+    CAP_TPL_LIST: 1,
+    CAP_TPL_LIST_ANY: 1,
+    CAP_TPL_READFS: 1,
+    CAP_TPL_READFS_ANY: 1,
 }
 
 // Capabilities stored in the VM config (access)
 var VMAccessCaps = Capabilities {
-	CAP_VM_SET_ACCESS: 1,
-	CAP_VM_DESTROY: 1,
-	CAP_VM_EDIT: 1,
-	CAP_VM_START: 1,
-	CAP_VM_STOP: 1,
-	CAP_VM_REBOOT: 1,
-	CAP_VM_LIST: 1,
-	CAP_VM_READFS: 1,
-	CAP_VM_WRITEFS: 1,
+    CAP_VM_SET_ACCESS: 1,
+    CAP_VM_DESTROY: 1,
+    CAP_VM_EDIT: 1,
+    CAP_VM_START: 1,
+    CAP_VM_STOP: 1,
+    CAP_VM_REBOOT: 1,
+    CAP_VM_LIST: 1,
+    CAP_VM_READFS: 1,
+    CAP_VM_WRITEFS: 1,
 }
 
 // Returns true if the string cap matches a user capability
 func IsUserCapValid(cap string) bool {
-	_, exists := userCaps[cap]
-	return exists
+    _, exists := userCaps[cap]
+    return exists
 }
 
 // Returns true if the string cap matches a VM access capability
 func IsVMAccessCapValid(cap string) bool {
-	_, exists := VMAccessCaps[cap]
-	return exists
+    _, exists := VMAccessCaps[cap]
+    return exists
 }
 
 // Validates all user capabilities.
 func ValidateUserCaps(caps Capabilities) error {
-	for cap, _ := range caps {
-		if (!IsUserCapValid(cap)) {
-			return errors.New("Invalid capability: "+cap)
-		}
-	}
-	return nil
+    for cap, _ := range caps {
+        if (!IsUserCapValid(cap)) {
+            return errors.New("Invalid capability: "+cap)
+        }
+    }
+    return nil
 }
 
 // Validates all VM access capabilities.
 func ValidateVMAccessCaps(caps Capabilities) error {
-	for cap, _ := range caps {
-		if (!IsVMAccessCapValid(cap)) {
-			return errors.New("Invalid capability: "+cap)
-		}
-	}
-	return nil
+    for cap, _ := range caps {
+        if (!IsVMAccessCapValid(cap)) {
+            return errors.New("Invalid capability: "+cap)
+        }
+    }
+    return nil
 }
diff --git a/src/cleaner/cleaner.go b/src/cleaner/cleaner.go
index 187255c5d93f4c43f34c3cacc6d3d08deae66676..977417f0349503445dbe714b4200e23f907b3478 100644
--- a/src/cleaner/cleaner.go
+++ b/src/cleaner/cleaner.go
@@ -1,11 +1,11 @@
 package cleaner
 
 import (
-	"os"
-	"time"
-	"strings"
-	"path/filepath"
-	"nexus-server/logger"
+    "os"
+    "time"
+    "strings"
+    "path/filepath"
+    "nexus-server/logger"
 )
 
 // Due to a bug in Echo's upload via HTTPS, many files whose's names start
@@ -13,51 +13,51 @@ import (
 // This thread deletes them to prevent saturating the system's disk space.
 
 const (
-	periodTimeInMin = 45
-	deleteOlderThanInMin = 30
+    periodTimeInMin = 45
+    deleteOlderThanInMin = 30
 )
 
 var log = logger.GetInstance()
 
 func isOlderThanMinutes(fi os.FileInfo, n time.Duration) bool {
-	return time.Now().Sub(fi.ModTime()) > n*time.Minute
+    return time.Now().Sub(fi.ModTime()) > n*time.Minute
 }
 
-func cleanup() {  
-	dir := "/tmp"
-
-	log.Info("Cleanup thread configured to run every ", periodTimeInMin, " minutes and to delete uploaded files in ", dir, " last accessed more than ",deleteOlderThanInMin, " minutes ago")
-
-	for {
-		log.Debug("Cleanup thread: checking for files to delete...")
-		openDir, err := os.Open(dir)
-		if err != nil {
-			log.Error("Cleanup thread exited with error: "+err.Error())
-			return
-		}
-		// Retrieves all files entries in the directory (0 = all files in the directory).
-		files, err := openDir.Readdir(0)
-		if err != nil {
-			log.Error("Cleanup thread error: "+err.Error())
-		} else {
-			for _, f := range(files) {
-				if !f.IsDir() && f.Mode().IsRegular()  {
-					path := filepath.Join(dir, f.Name())
-					if strings.HasPrefix(f.Name(), "multipart-") && isOlderThanMinutes(f, deleteOlderThanInMin) {
-						if err := os.Remove(path); err != nil {
-							log.Error("Cleanup thread error: "+err.Error())
-						} else {
-							log.Info("Cleanup thread: deleted ", path)
-						}
-					}
-				}
-			}
-			openDir.Close()
-		}
-		time.Sleep(periodTimeInMin*time.Minute)
-	}
+func cleanup() {
+    dir := "/tmp"
+
+    log.Info("Cleanup thread configured to run every ", periodTimeInMin, " minutes and to delete uploaded files in ", dir, " last accessed more than ",deleteOlderThanInMin, " minutes ago")
+
+    for {
+        log.Debug("Cleanup thread: checking for files to delete...")
+        openDir, err := os.Open(dir)
+        if err != nil {
+            log.Error("Cleanup thread exited with error: "+err.Error())
+            return
+        }
+        // Retrieves all files entries in the directory (0 = all files in the directory).
+        files, err := openDir.Readdir(0)
+        if err != nil {
+            log.Error("Cleanup thread error: "+err.Error())
+        } else {
+            for _, f := range(files) {
+                if !f.IsDir() && f.Mode().IsRegular()  {
+                    path := filepath.Join(dir, f.Name())
+                    if strings.HasPrefix(f.Name(), "multipart-") && isOlderThanMinutes(f, deleteOlderThanInMin) {
+                        if err := os.Remove(path); err != nil {
+                            log.Error("Cleanup thread error: "+err.Error())
+                        } else {
+                            log.Info("Cleanup thread: deleted ", path)
+                        }
+                    }
+                }
+            }
+            openDir.Close()
+        }
+        time.Sleep(periodTimeInMin*time.Minute)
+    }
 }
 
 func Start() {
-	go cleanup()
+    go cleanup()
 }
\ No newline at end of file
diff --git a/src/consts/consts.go b/src/consts/consts.go
index 5d8b3714f7eaf4a6fcd142b0f2292564683d575a..9f197530a362515edc7a45282b5c1158084167dc 100644
--- a/src/consts/consts.go
+++ b/src/consts/consts.go
@@ -1,22 +1,22 @@
 package consts
 
 const (
-	DefaultLogLevel = "info"
+    DefaultLogLevel = "info"
 
-	APIDefaultPort = 1077
-	APIPortMin     = 1025
-	APIPortMax     = 1099
+    APIDefaultPort = 1077
+    APIPortMin     = 1025
+    APIPortMax     = 1099
 
-	VMSpiceMinPort = 1100
-	VMSpiceMaxPort = 65000
+    VMSpiceMinPort = 1100
+    VMSpiceMaxPort = 65000
 
-	MaxUploadSize = "30G"
+    MaxUploadSize = "30G"
 
-	// We estimate that KVM allows for this amount of RAM saving in %
-	// (due to page sharing across VMs).
-	KsmRamSaving = 0.3
+    // We estimate that KVM allows for this amount of RAM saving in %
+    // (due to page sharing across VMs).
+    KsmRamSaving = 0.3
 
-	// To prevent RAM saturation, we refuse running new VMs if more than
-	// this amount of memory is being used (in %).
-	RamUsageLimit = .85
+    // To prevent RAM saturation, we refuse running new VMs if more than
+    // this amount of memory is being used (in %).
+    RamUsageLimit = .85
 )
diff --git a/src/exec/Guestfish.go b/src/exec/Guestfish.go
index e366bcb3cf3b9f6773147e1f80751a25c5e6ffca..751707250d6feea0dfa9ec517b30a3a6fd9e6851 100644
--- a/src/exec/Guestfish.go
+++ b/src/exec/Guestfish.go
@@ -1,57 +1,57 @@
 package exec
 
 import (
-	"fmt"
-	"os/exec"
-	"strings"
-	"errors"
+    "fmt"
+    "os/exec"
+    "strings"
+    "errors"
 )
 
 const (
-	guestfishBinary = "guestfish"
+    guestfishBinary = "guestfish"
 )
 
 // Checks guestfish is available.
 func CheckGuestfish() error {
-	output, err := exec.Command(guestfishBinary, "--version").Output()
+    output, err := exec.Command(guestfishBinary, "--version").Output()
     if err != nil {
         return errors.New(guestfishBinary+" is required but not found. On Ubuntu/Debian, it can be installed with \"sudo apt-get install guestfish\".")
-	}
-	out := string(output)
-	lines := strings.Split(out, "\n")
-	fields := strings.Split(lines[0], " ")
-	if len(fields) < 2 {
-		return errors.New("Failed extracting "+guestfishBinary+" version number!")
-	}
-	cmd := fields[0]
-	if cmd != guestfishBinary {
-		return errors.New(guestfishBinary+" is required, but not found.")
-	}
-	return nil
+    }
+    out := string(output)
+    lines := strings.Split(out, "\n")
+    fields := strings.Split(lines[0], " ")
+    if len(fields) < 2 {
+        return errors.New("Failed extracting "+guestfishBinary+" version number!")
+    }
+    cmd := fields[0]
+    if cmd != guestfishBinary {
+        return errors.New(guestfishBinary+" is required, but not found.")
+    }
+    return nil
 }
 
 // Copies and unarchives a local tar.gz archive into a directory (vmDir) inside the VM's filesystem.
 func CopyToVM(vmDiskFile, tarGzFile, vmDir string) error {
-	cmd := exec.Command(guestfishBinary, "--rw", "-i", "tar-in", "-a", vmDiskFile, tarGzFile, vmDir, "compress:gzip")
-	stdoutStderr, err := cmd.CombinedOutput()
-	if err != nil {
-		output := fmt.Sprintf("[%s]", stdoutStderr)
-		msg := "Failed writing to \""+vmDir+"\" in qcow ("+vmDiskFile+")"
-		log.Error(msg+": "+output)
-		return errors.New(msg)
-	}
-	return nil
+    cmd := exec.Command(guestfishBinary, "--rw", "-i", "tar-in", "-a", vmDiskFile, tarGzFile, vmDir, "compress:gzip")
+    stdoutStderr, err := cmd.CombinedOutput()
+    if err != nil {
+        output := fmt.Sprintf("[%s]", stdoutStderr)
+        msg := "Failed writing to \""+vmDir+"\" in qcow ("+vmDiskFile+")"
+        log.Error(msg+": "+output)
+        return errors.New(msg)
+    }
+    return nil
 }
 
 // Recursively copies a directory in the VM's filesystem (vmDir) into a tar.gz archive.
 func CopyFromVM(vmDiskFile, vmDir, tarGzFile string) error {
-	cmd := exec.Command(guestfishBinary, "--ro", "-i", "tar-out",  "-a", vmDiskFile, vmDir, tarGzFile, "compress:gzip")
-	stdoutStderr, err := cmd.CombinedOutput()
-	if err != nil {
-		output := fmt.Sprintf("[%s]", stdoutStderr)
-		msg := "Failed reading \""+vmDir+"\" in qcow ("+vmDiskFile+"): "+output
-		log.Error(msg)
-		return errors.New(msg)
-	}
-	return nil
+    cmd := exec.Command(guestfishBinary, "--ro", "-i", "tar-out",  "-a", vmDiskFile, vmDir, tarGzFile, "compress:gzip")
+    stdoutStderr, err := cmd.CombinedOutput()
+    if err != nil {
+        output := fmt.Sprintf("[%s]", stdoutStderr)
+        msg := "Failed reading \""+vmDir+"\" in qcow ("+vmDiskFile+"): "+output
+        log.Error(msg)
+        return errors.New(msg)
+    }
+    return nil
 }
diff --git a/src/exec/QemuImg.go b/src/exec/QemuImg.go
index 3335301ff6d05cc4079ad58f66a9b8899b1cef8b..c27d4f349061e3c6e6f0976156674c3036566d16 100644
--- a/src/exec/QemuImg.go
+++ b/src/exec/QemuImg.go
@@ -1,64 +1,64 @@
 package exec
 
 import (
-	"fmt"
-	"os/exec"
-	"strings"
-	"errors"
-	"strconv"
-	"nexus-server/logger"
+    "fmt"
+    "os/exec"
+    "strings"
+    "errors"
+    "strconv"
+    "nexus-server/logger"
 )
 
 const (
-	qemuimgBinary = "qemu-img"
-	qemuimgBinaryMinVersion = 4
+    qemuimgBinary = "qemu-img"
+    qemuimgBinaryMinVersion = 4
 )
 
 var log = logger.GetInstance()
 
 // Checks qemu-img is available and the version is recent enough.
 func CheckQemuImg() error {
-	output, err := exec.Command(qemuimgBinary, "--version").Output()
+    output, err := exec.Command(qemuimgBinary, "--version").Output()
     if err != nil {
         return errors.New(qemuimgBinary+" is required but not found. On Ubuntu/Debian, it can be installed with \"sudo apt-get install qemu-utils\".")
-	}
-	out := string(output)
-	lines := strings.Split(out, "\n")
-	fields := strings.Split(lines[0], " ")
-	if len(fields) < 3 {
-		return errors.New("Failed extracting "+qemuimgBinary+" version number!")
-	}
-	v := fields[2]
-	majorVersionNumber, err := strconv.Atoi(string(v[0]))
+    }
+    out := string(output)
+    lines := strings.Split(out, "\n")
+    fields := strings.Split(lines[0], " ")
+    if len(fields) < 3 {
+        return errors.New("Failed extracting "+qemuimgBinary+" version number!")
+    }
+    v := fields[2]
+    majorVersionNumber, err := strconv.Atoi(string(v[0]))
     if err != nil {
         return errors.New("Failed extracting "+qemuimgBinary+" version number: "+err.Error())
-	}
-	if majorVersionNumber < qemuimgBinaryMinVersion {
-		return errors.New(qemuimgBinary+" "+strconv.Itoa(qemuimgBinaryMinVersion)+".0.0 or newer is required. Found version "+v+".")
-	}
-	return nil
+    }
+    if majorVersionNumber < qemuimgBinaryMinVersion {
+        return errors.New(qemuimgBinary+" "+strconv.Itoa(qemuimgBinaryMinVersion)+".0.0 or newer is required. Found version "+v+".")
+    }
+    return nil
 }
 
 // Creates a VM disk image baked by a base image (template).
 func QemuImgCreate(templateDiskFile, vmDiskFile string) error {
-	cmd := exec.Command(qemuimgBinary, "create", "-F", "qcow2", "-b", templateDiskFile, "-f", "qcow2", vmDiskFile)
-	stdoutStderr, err := cmd.CombinedOutput()
-	if err != nil {
-		output := fmt.Sprintf("[%s]", stdoutStderr)
-		log.Error("Failed creating VM disk image: "+output)
-		return errors.New("Failed creating VM disk image")
-	}
-	return nil
+    cmd := exec.Command(qemuimgBinary, "create", "-F", "qcow2", "-b", templateDiskFile, "-f", "qcow2", vmDiskFile)
+    stdoutStderr, err := cmd.CombinedOutput()
+    if err != nil {
+        output := fmt.Sprintf("[%s]", stdoutStderr)
+        log.Error("Failed creating VM disk image: "+output)
+        return errors.New("Failed creating VM disk image")
+    }
+    return nil
 }
 
 // Rebases a VM overlay image in order to become a standalone image.
 func QemuImgRebase(overlayFile string) error {
-	cmd := exec.Command(qemuimgBinary, "rebase", "-b", "", overlayFile)
-	stdoutStderr, err := cmd.CombinedOutput()
-	if err != nil {
-		output := fmt.Sprintf("[%s]", stdoutStderr)
-		log.Error("Failed rebasing template disk from VM: "+": "+output)
-		return errors.New("Failed rebasing template disk from VM")
-	}
-	return nil
+    cmd := exec.Command(qemuimgBinary, "rebase", "-b", "", overlayFile)
+    stdoutStderr, err := cmd.CombinedOutput()
+    if err != nil {
+        output := fmt.Sprintf("[%s]", stdoutStderr)
+        log.Error("Failed rebasing template disk from VM: "+": "+output)
+        return errors.New("Failed rebasing template disk from VM")
+    }
+    return nil
 }
diff --git a/src/exec/QemuSystem.go b/src/exec/QemuSystem.go
index aae61a3c64d9827f77dae24da80ba392093fca67..e8524aa9c31e9f072702eba3b68a342df209b6d9 100644
--- a/src/exec/QemuSystem.go
+++ b/src/exec/QemuSystem.go
@@ -1,63 +1,63 @@
 package exec
 
 import (
-	"os/exec"
-	"strings"
-	"errors"
-	"strconv"
-	"nexus-server/utils"
+    "os/exec"
+    "strings"
+    "errors"
+    "strconv"
+    "nexus-server/utils"
 )
 
 const (
-	qemusystemBinary = "qemu-system-x86_64"
-	qemusystemMinVersion = 6
+    qemusystemBinary = "qemu-system-x86_64"
+    qemusystemMinVersion = 6
 )
 
 // Check qemu-system-x86_64 is available and the version is recent enough.
 func CheckQemuSystem() error {
-	output, err := exec.Command(qemusystemBinary, "-version").Output()
+    output, err := exec.Command(qemusystemBinary, "-version").Output()
     if err != nil {
         return errors.New(qemusystemBinary+" is required but not found. On Ubuntu/Debian, it can be installed with \"sudo apt-get install qemu-system-x86\".")
-	}
-	out := string(output)
-	lines := strings.Split(out, "\n")
-	fields := strings.Split(lines[0], " ")
-	if len(fields) < 4 {
-		return errors.New("Failed extracting "+qemusystemBinary+" version number!")
-	}
-	v := fields[3]
-	majorVersionNumber, err := strconv.Atoi(string(v[0]))
+    }
+    out := string(output)
+    lines := strings.Split(out, "\n")
+    fields := strings.Split(lines[0], " ")
+    if len(fields) < 4 {
+        return errors.New("Failed extracting "+qemusystemBinary+" version number!")
+    }
+    v := fields[3]
+    majorVersionNumber, err := strconv.Atoi(string(v[0]))
     if err != nil {
         return errors.New("Failed extracting "+qemusystemBinary+" version number: "+err.Error())
-	}
-	if majorVersionNumber < qemusystemMinVersion {
-		return errors.New(qemusystemBinary+" "+strconv.Itoa(qemusystemMinVersion)+".0.0 or newer is required. Found version "+v+".")
-	}
-	return nil
+    }
+    if majorVersionNumber < qemusystemMinVersion {
+        return errors.New(qemusystemBinary+" "+strconv.Itoa(qemusystemMinVersion)+".0.0 or newer is required. Found version "+v+".")
+    }
+    return nil
 }
 
 // Creates a qemu-system command.
 // The nic argument must be either "none" or "user".
 func NewQemuSystem(qgaSock string, cpus, ram int, nic, diskFile string, spicePort int, secretPwdFile, certDir string) (*exec.Cmd, error) {
-	nicArgs := "none"
-	if nic == "user" {
-		addr, err := utils.RandMacAddress()
-		if err != nil {
-			return nil, errors.New("Failed executing VM: MAC address generation error")
-		}
-		nicArgs = "user,mac="+addr+",model=virtio-net-pci"
-	}
+    nicArgs := "none"
+    if nic == "user" {
+        addr, err := utils.RandMacAddress()
+        if err != nil {
+            return nil, errors.New("Failed executing VM: MAC address generation error")
+        }
+        nicArgs = "user,mac="+addr+",model=virtio-net-pci"
+    }
 
-	// Remarks:
-	// 1) This device is to allow copy/paste between guest & client
-	//  -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0
-	// 2) For sound support: "-soundhw hda"
-	// 3) For shared folder with the host:
-	//   - QEMU: virtfs local,path=/tmp/pipo,mount_tag=sharedfs,security_model=none
-	//   - In the guest: mkdir shared && sudo mount -t 9p sharedfs shared
-	// 4) For QEMU Guest Agent support:
-	//  -device virtio-serial -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 -chardev socket,path=path_to_sock_file,server=on,wait=off,id=qga0
-	cmd := exec.Command(qemusystemBinary, "-enable-kvm", "-cpu", "host", "-smp", "cpus="+strconv.Itoa(cpus), "-m", strconv.Itoa(ram), "-drive", "file="+diskFile+",index=0,media=disk,format=qcow2,discard=unmap,detect-zeroes=unmap,if=virtio", "-vga", "virtio", "-device", "virtio-serial-pci", "-object", "secret,id=sec,file="+secretPwdFile+",format=base64", "-spice", "tls-port="+strconv.Itoa(spicePort)+",password-secret=sec,x509-dir="+certDir, "-device", "virtserialport,chardev=spicechannel0,name=com.redhat.spice.0", "-chardev", "spicevmc,id=spicechannel0,name=vdagent", "-nic", nicArgs, "-device", "virtio-serial", "-device", "virtserialport,chardev=qga0,name=org.qemu.guest_agent.0", "-chardev", "socket,path="+qgaSock+",server=on,wait=off,id=qga0")
+    // Remarks:
+    // 1) This device is to allow copy/paste between guest & client
+    //  -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0
+    // 2) For sound support: "-soundhw hda"
+    // 3) For shared folder with the host:
+    //   - QEMU: virtfs local,path=/tmp/pipo,mount_tag=sharedfs,security_model=none
+    //   - In the guest: mkdir shared && sudo mount -t 9p sharedfs shared
+    // 4) For QEMU Guest Agent support:
+    //  -device virtio-serial -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 -chardev socket,path=path_to_sock_file,server=on,wait=off,id=qga0
+    cmd := exec.Command(qemusystemBinary, "-enable-kvm", "-cpu", "host", "-smp", "cpus="+strconv.Itoa(cpus), "-m", strconv.Itoa(ram), "-drive", "file="+diskFile+",index=0,media=disk,format=qcow2,discard=unmap,detect-zeroes=unmap,if=virtio", "-vga", "virtio", "-device", "virtio-serial-pci", "-object", "secret,id=sec,file="+secretPwdFile+",format=base64", "-spice", "tls-port="+strconv.Itoa(spicePort)+",password-secret=sec,x509-dir="+certDir, "-device", "virtserialport,chardev=spicechannel0,name=com.redhat.spice.0", "-chardev", "spicevmc,id=spicechannel0,name=vdagent", "-nic", nicArgs, "-device", "virtio-serial", "-device", "virtserialport,chardev=qga0,name=org.qemu.guest_agent.0", "-chardev", "socket,path="+qgaSock+",server=on,wait=off,id=qga0")
 
-	return cmd, nil
+    return cmd, nil
 }
diff --git a/src/logger/logger.go b/src/logger/logger.go
index 5a86f38ab972e50806448fa49fac4adaa48e8d0a..7aa4884e09a9dc86af2b10d968d7fd37ec949962 100644
--- a/src/logger/logger.go
+++ b/src/logger/logger.go
@@ -1,22 +1,22 @@
 package logger
 
 import (
-	"sync"
-	"github.com/sirupsen/logrus"
+    "sync"
+    "github.com/sirupsen/logrus"
 )
 
 var log *logrus.Logger
 var once sync.Once
 
 func GetInstance() *logrus.Logger {
-	once.Do(func() {
-		log = logrus.New()
-		//log.SetReportCaller(true)
-		log.SetFormatter(&logrus.TextFormatter{
-			//FullTimestamp: true,
-			DisableTimestamp: true,
-		})
-	})
+    once.Do(func() {
+        log = logrus.New()
+        //log.SetReportCaller(true)
+        log.SetFormatter(&logrus.TextFormatter{
+            //FullTimestamp: true,
+            DisableTimestamp: true,
+        })
+    })
     return log
 }
 
diff --git a/src/nexus-server.go b/src/nexus-server.go
index 17df7bbbfb52939d8b34beb9fa3304502184dd60..83cd34b821aed66a21fc070801a87415f2ba8031 100644
--- a/src/nexus-server.go
+++ b/src/nexus-server.go
@@ -1,99 +1,99 @@
 package main
 
 import (
-	"os"
-	"fmt"
-	"path"
-	"flag"
-	"strconv"
-	"strings"
-	"nexus-server/vms"
-	"nexus-server/exec"
-	"nexus-server/paths"
-	"nexus-server/users"
-	"nexus-server/utils"
-	"nexus-server/router"
-	"nexus-server/logger"
-	"nexus-server/consts"
-	"nexus-server/cleaner"
-	"nexus-server/version"
-	"github.com/sirupsen/logrus"
+    "os"
+    "fmt"
+    "path"
+    "flag"
+    "strconv"
+    "strings"
+    "nexus-server/vms"
+    "nexus-server/exec"
+    "nexus-server/paths"
+    "nexus-server/users"
+    "nexus-server/utils"
+    "nexus-server/router"
+    "nexus-server/logger"
+    "nexus-server/consts"
+    "nexus-server/cleaner"
+    "nexus-server/version"
+    "github.com/sirupsen/logrus"
 )
 
 var log = logger.GetInstance()
 
 func main() {
-	log.SetLevel(logrus.InfoLevel)
+    log.SetLevel(logrus.InfoLevel)
 
-	var appname = path.Base(os.Args[0])
-	log.Info(appname+" version "+version.Get().String())
+    var appname = path.Base(os.Args[0])
+    log.Info(appname+" version "+version.Get().String())
 
-	// These two lines must be executed very early on (basically, here).
-	paths.Init()
-	utils.RandInit()
+    // These two lines must be executed very early on (basically, here).
+    paths.Init()
+    utils.RandInit()
 
-	if err := exec.CheckQemuSystem(); err != nil {
-		log.Fatal(err)
-	}
-	if err := exec.CheckQemuImg(); err != nil {
-		log.Fatal(err)
-	}
-	if err := exec.CheckGuestfish(); err != nil {
-		log.Fatal(err)
-	}
+    if err := exec.CheckQemuSystem(); err != nil {
+        log.Fatal(err)
+    }
+    if err := exec.CheckQemuImg(); err != nil {
+        log.Fatal(err)
+    }
+    if err := exec.CheckGuestfish(); err != nil {
+        log.Fatal(err)
+    }
 
-	usage := func() {
-		fmt.Println("Usage of "+appname+":")
-		flag.PrintDefaults()
-		os.Exit(1)
-	}
+    usage := func() {
+        fmt.Println("Usage of "+appname+":")
+        flag.PrintDefaults()
+        os.Exit(1)
+    }
 
-	loglevelFlag := flag.String("l", consts.DefaultLogLevel, "Log level: debug, info, warn, error, fatal")
-	portMin := strconv.Itoa(consts.APIPortMin)
-	portMax := strconv.Itoa(consts.APIPortMax)
-	portFlag := flag.Int("p", consts.APIDefaultPort, "Port on which to listen to (between "+portMin+" and "+portMax+")")
-	flag.Parse()
+    loglevelFlag := flag.String("l", consts.DefaultLogLevel, "Log level: debug, info, warn, error, fatal")
+    portMin := strconv.Itoa(consts.APIPortMin)
+    portMax := strconv.Itoa(consts.APIPortMax)
+    portFlag := flag.Int("p", consts.APIDefaultPort, "Port on which to listen to (between "+portMin+" and "+portMax+")")
+    flag.Parse()
 
-	loglevelStr := strings.ToLower(*loglevelFlag)
-	switch loglevelStr {
-		case "debug":
-			log.SetLevel(logrus.DebugLevel)
-		case "info":
-			log.SetLevel(logrus.InfoLevel)
-		case "warn":
-			log.SetLevel(logrus.WarnLevel)
-		case "error":
-			log.SetLevel(logrus.ErrorLevel)
-		case "fatal":
-			log.SetLevel(logrus.FatalLevel)
-		default:
-			fmt.Println("Invalid log level!")
-			usage()
-	}
+    loglevelStr := strings.ToLower(*loglevelFlag)
+    switch loglevelStr {
+        case "debug":
+            log.SetLevel(logrus.DebugLevel)
+        case "info":
+            log.SetLevel(logrus.InfoLevel)
+        case "warn":
+            log.SetLevel(logrus.WarnLevel)
+        case "error":
+            log.SetLevel(logrus.ErrorLevel)
+        case "fatal":
+            log.SetLevel(logrus.FatalLevel)
+        default:
+            fmt.Println("Invalid log level!")
+            usage()
+    }
 
-	port := *portFlag
-	if port < consts.APIPortMin || port > consts.APIPortMax {
-		fmt.Println("Invalid port number!")
-		usage()
-	}
+    port := *portFlag
+    if port < consts.APIPortMin || port > consts.APIPortMax {
+        fmt.Println("Invalid port number!")
+        usage()
+    }
 
-	err := users.InitUsers()
-	if err != nil {
-		log.Fatal(err.Error())
-	}
+    err := users.InitUsers()
+    if err != nil {
+        log.Fatal(err.Error())
+    }
 
-	// Templates are required by VMs hence they're loaded first.
-	err = vms.InitTemplates()
-	if err != nil {
-		log.Fatal(err.Error())
-	}
+    // Templates are required by VMs hence they're loaded first.
+    err = vms.InitTemplates()
+    if err != nil {
+        log.Fatal(err.Error())
+    }
 
-	err = vms.InitVMs()
-	if err != nil {
-		log.Fatal(err.Error())
-	}
+    err = vms.InitVMs()
+    if err != nil {
+        log.Fatal(err.Error())
+    }
 
-	cleaner.Start()
+    cleaner.Start()
 
-	router.New().Start(port)
+    router.New().Start(port)
 }
diff --git a/src/paths/paths.go b/src/paths/paths.go
index 766851c66de040bcf09ecfa72bb24d2d114d0dd8..12f78fb40560ec1935012e66227736b18637ff1a 100644
--- a/src/paths/paths.go
+++ b/src/paths/paths.go
@@ -1,37 +1,37 @@
 package paths
 
 import (
-	"path/filepath"
-	"nexus-server/logger"
+    "path/filepath"
+    "nexus-server/logger"
 )
 
 type Paths struct {
-	ConfigDir string
-	UsersFile string
-	DataDir string
-	VMsDir string
-	TemplatesDir string
-	NexusPkiDir string
-	TmpDir string
+    ConfigDir string
+    UsersFile string
+    DataDir string
+    VMsDir string
+    TemplatesDir string
+    NexusPkiDir string
+    TmpDir string
 }
 
 var log = logger.GetInstance()
 var paths *Paths
 
 func GetInstance() *Paths {
-	return paths
+    return paths
 }
 
 func Init() {
-	config := "../config"
-	data := "../data"
-	paths = &Paths {
-		ConfigDir: config,
-		UsersFile: filepath.Join(config, "/users.json"),
-		DataDir: data,
-		VMsDir: filepath.Join(data, "/vms"),
-		TemplatesDir: filepath.Join(data, "/templates"),
-		NexusPkiDir: filepath.Join(config, "/pki/server-nexus"),
-		TmpDir: filepath.Join(data, "/tmp"),
-	}
+    config := "../config"
+    data := "../data"
+    paths = &Paths {
+        ConfigDir: config,
+        UsersFile: filepath.Join(config, "/users.json"),
+        DataDir: data,
+        VMsDir: filepath.Join(data, "/vms"),
+        TemplatesDir: filepath.Join(data, "/templates"),
+        NexusPkiDir: filepath.Join(config, "/pki/server-nexus"),
+        TmpDir: filepath.Join(data, "/tmp"),
+    }
 }
diff --git a/src/qga/qga.go b/src/qga/qga.go
index ae4195d55cc46311f0e4bdcc039402f74764bde0..3a7a4d6ba85a380c8f7bf3c6204cc37212f784da 100644
--- a/src/qga/qga.go
+++ b/src/qga/qga.go
@@ -1,21 +1,21 @@
 package qga
 
 import (
-	"fmt"
-	"net"
-	"errors"
-	"encoding/base64"
-	"nexus-server/logger"
+    "fmt"
+    "net"
+    "errors"
+    "encoding/base64"
+    "nexus-server/logger"
 )
 
 type QGACon struct {
-	sock net.Conn
+    sock net.Conn
 }
 
 var log = logger.GetInstance()
 
 func New() *QGACon {
-	return &QGACon{}
+    return &QGACon{}
 }
 
 // TODO
@@ -24,102 +24,102 @@ func New() *QGACon {
 
 // sockAddr is the path to a UNIX domain socket.
 func (q *QGACon)Open(sockAddr string) error {
-	con, err := net.Dial("unix", sockAddr)
-	if err != nil {
-		return err
-	}
-	q.sock = con
-	return nil
+    con, err := net.Dial("unix", sockAddr)
+    if err != nil {
+        return err
+    }
+    q.sock = con
+    return nil
 }
 
 func (q *QGACon)Close() error {
-	return q.sock.Close()
+    return q.sock.Close()
 }
 
 // Send a shutdown command to the guest OS.
 func (q *QGACon)SendShutdown() error {
-	_, err := q.sock.Write([]byte(`
-	{
-		"execute": "guest-shutdown"
-	}
-	`))
-	return err
+    _, err := q.sock.Write([]byte(`
+    {
+        "execute": "guest-shutdown"
+    }
+    `))
+    return err
 }
 
 // Send a reboot command to the guest OS.
 func (q *QGACon)SendReboot() error {
-	return q.SendCmd("reboot")
+    return q.SendCmd("reboot")
 }
 
 // Send a forced reboot command to the guest OS.
 func (q *QGACon)SendForcedReboot() error {
-	_, err := q.sock.Write([]byte(`
-	{
-		"execute":"guest-exec",
-		"arguments": {
-			"path":"reboot",
-			"arg": ["--force"]
-		}
-	}
-	`))
-	return err
+    _, err := q.sock.Write([]byte(`
+    {
+        "execute":"guest-exec",
+        "arguments": {
+            "path":"reboot",
+            "arg": ["--force"]
+        }
+    }
+    `))
+    return err
 }
 
 // Send a command to the guest OS.
 func (q *QGACon)SendCmd(cmd string) error {
-	_, err := q.sock.Write([]byte(`
-	{
-		"execute":"guest-exec",
-		"arguments": {
-			"path":"`+cmd+`"
-		}
-	}
-	`))
-	return err
+    _, err := q.sock.Write([]byte(`
+    {
+        "execute":"guest-exec",
+        "arguments": {
+            "path":"`+cmd+`"
+        }
+    }
+    `))
+    return err
 }
 
 // TODO: work in progress...
 func (q *QGACon)WriteFile(filePath string) error {
-	filePath = "/home/nexus/pipo.txt"
-	_, err := q.sock.Write([]byte(`
-	{
-		"execute":"guest-file-open",
-		"arguments": {
-			"path":"`+filePath+`",
-			"mode":"w+"
-		}
-	}
-	`))
-	buf := make([]byte, 128)
-	_, err = q.sock.Read(buf)
-	if err != nil {
-		return err
-	}
-	handle := string(buf[:])
-	fmt.Println("handle: ",handle)
+    filePath = "/home/nexus/pipo.txt"
+    _, err := q.sock.Write([]byte(`
+    {
+        "execute":"guest-file-open",
+        "arguments": {
+            "path":"`+filePath+`",
+            "mode":"w+"
+        }
+    }
+    `))
+    buf := make([]byte, 128)
+    _, err = q.sock.Read(buf)
+    if err != nil {
+        return err
+    }
+    handle := string(buf[:])
+    fmt.Println("handle: ",handle)
 
-	// content must be encoded in base64
-	content := "Hello ma poule!"
-	contentB64 := base64.StdEncoding.EncodeToString([]byte(content))
-	status, err := q.sock.Write([]byte(`
-	{
-		"execute":"guest-file-write",
-		"arguments": {
-			"handle":1000,
-			"buf-b64":"`+contentB64+`"
-		}
-	}
-	`))
-	status, err = q.sock.Write([]byte(`
-	{
-		"execute":"guest-file-close",
-		"arguments": {
-			"handle":1000
-		}
-	}
-	`))
-	if status < 0 {
-		return errors.New("write error")
-	}
-	return err
+    // content must be encoded in base64
+    content := "Hello ma poule!"
+    contentB64 := base64.StdEncoding.EncodeToString([]byte(content))
+    status, err := q.sock.Write([]byte(`
+    {
+        "execute":"guest-file-write",
+        "arguments": {
+            "handle":1000,
+            "buf-b64":"`+contentB64+`"
+        }
+    }
+    `))
+    status, err = q.sock.Write([]byte(`
+    {
+        "execute":"guest-file-close",
+        "arguments": {
+            "handle":1000
+        }
+    }
+    `))
+    if status < 0 {
+        return errors.New("write error")
+    }
+    return err
 }
diff --git a/src/router/auth.go b/src/router/auth.go
index ffcee8fc5b9a1c73ec7c310d35ebb7f019858a45..049a21829a4848399101fe2df91f273fdd6682cb 100644
--- a/src/router/auth.go
+++ b/src/router/auth.go
@@ -1,43 +1,43 @@
 package router
 
 import (
-	"time"
-	"errors"
-	"net/http"
-	"nexus-server/users"
-	"golang.org/x/crypto/bcrypt"
-	"github.com/golang-jwt/jwt"
-	"github.com/labstack/echo/v4"
-	"github.com/labstack/echo/v4/middleware"
-	"github.com/go-playground/validator/v10"
-	"github.com/sethvargo/go-password/password"
+    "time"
+    "errors"
+    "net/http"
+    "nexus-server/users"
+    "golang.org/x/crypto/bcrypt"
+    "github.com/golang-jwt/jwt"
+    "github.com/labstack/echo/v4"
+    "github.com/labstack/echo/v4/middleware"
+    "github.com/go-playground/validator/v10"
+    "github.com/sethvargo/go-password/password"
 )
 
 const (
-	// Access token expiration time.
-	accessTokenExpirationTimeInHours = 12
+    // Access token expiration time.
+    accessTokenExpirationTimeInHours = 12
 
-	// Number of login attemps after which an account is locked.
-	maxloginAttempts = 5
-	// How long an account is locked for.
-	lockedTimeInHours = 4.0
+    // Number of login attemps after which an account is locked.
+    maxloginAttempts = 5
+    // How long an account is locked for.
+    lockedTimeInHours = 4.0
 )
 
 // jwt.StandardClaims is added as an embedded type to provide fields like user email and expiration time.
 type CustomClaims struct {
-	Email string
-	jwt.StandardClaims
+    Email string
+    jwt.StandardClaims
 }
 
 // These fields must match the ones in user.User
 type Credentials struct {
-	Email string   `json:"email"  validate:"required,email"`
-	Pwd string     `json:"pwd"    validate:"required,min=8"`
+    Email string   `json:"email"  validate:"required,email"`
+    Pwd string     `json:"pwd"    validate:"required,min=8"`
 }
 
 type Auth struct {
-	users *users.Users
-	tokenAccess middleware.JWTConfig
+    users *users.Users
+    tokenAccess middleware.JWTConfig
 }
 
 var loginAttempts map[string]int  // Keeps track of the number of wrong logins.
@@ -46,142 +46,142 @@ var jwtSecretKey string
 
 // Creates an Auth object.
 func NewAuth(u *users.Users) (*Auth, error) {
-	loginAttempts = make(map[string]int)
-	loginLocked = make(map[string]time.Time)
-
-	// TODO: better to store jwtSecretKey in an env. variable?
-	// Generates a 64 characters long key with 20 digits, 0 symbols,
-	// allowing upper and lower case letters, and allowing repeat characters.
-	secret, err := password.Generate(64, 20, 0, false, true)
-	if err != nil {
-		return nil, errors.New("Secret generation error: "+err.Error())
-	}
-	jwtSecretKey = secret
-
-	return &Auth {
-		users : u,
-		tokenAccess : middleware.JWTConfig {
-			ContextKey: "user",
-			SigningKey: []byte(jwtSecretKey),
-			Claims:     &CustomClaims{},
-			ErrorHandlerWithContext: func(err error, c echo.Context) error {
-				return echo.NewHTTPError(http.StatusUnauthorized, "access denied")
-			},
-		},
-	}, nil
+    loginAttempts = make(map[string]int)
+    loginLocked = make(map[string]time.Time)
+
+    // TODO: better to store jwtSecretKey in an env. variable?
+    // Generates a 64 characters long key with 20 digits, 0 symbols,
+    // allowing upper and lower case letters, and allowing repeat characters.
+    secret, err := password.Generate(64, 20, 0, false, true)
+    if err != nil {
+        return nil, errors.New("Secret generation error: "+err.Error())
+    }
+    jwtSecretKey = secret
+
+    return &Auth {
+        users : u,
+        tokenAccess : middleware.JWTConfig {
+            ContextKey: "user",
+            SigningKey: []byte(jwtSecretKey),
+            Claims:     &CustomClaims{},
+            ErrorHandlerWithContext: func(err error, c echo.Context) error {
+                return echo.NewHTTPError(http.StatusUnauthorized, "access denied")
+            },
+        },
+    }, nil
 }
 
 // Token used by the JWT middleware to protect access to the specified group of routes.
 func (auth *Auth)GetTokenAccess() middleware.JWTConfig {
-	return auth.tokenAccess
+    return auth.tokenAccess
 }
 
 // curl --cacert ca.pem -X POST https://localhost:1077/login -H 'Content-Type: application/json' -d '{"email": "johndoe@nexus.org", "pwd":"the_user_password"}'
 // Returns a jwt token if authentication was successful:
 // {"token":"<jwt token>"}
 func (auth *Auth)Login(c echo.Context) error {
-	// Deserializes the JSON body and checks its validity.
-	reqUser := new(Credentials)
-	if err := decodeJson(c, &reqUser); err != nil {
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
-	if err := validator.New().Struct(reqUser); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// User exists?
-	user, err := auth.users.GetUserByEmail(reqUser.Email)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// Is user locked?
-	lockedTime, exists := loginLocked[user.Email]
-	if exists {
-		// If locked time has elapsed, unlock the account.
-		t := time.Now()
-		elapsedTime := t.Sub(lockedTime)
-		if elapsedTime.Hours() > lockedTimeInHours {
-			delete(loginLocked, user.Email)
-			delete(loginAttempts, user.Email)
-		} else {
-			return echo.NewHTTPError(http.StatusUnauthorized, "Account is locked")
-		}
-	}
-
-	// Checks the user password is correct.
-	// If a user enters the wrong password too many times, the account will be locked for a number of hours.
-	if err := bcrypt.CompareHashAndPassword([]byte(user.Pwd), []byte(reqUser.Pwd)); err != nil {
-		// Stores the number of attempted logins.
-		count, exists := loginAttempts[user.Email]
-		if exists {
-			loginAttempts[user.Email] = count+1
-			if count >= maxloginAttempts {
-				// Locks the account.
-				loginLocked[user.Email] = time.Now()
-				return echo.NewHTTPError(http.StatusUnauthorized, "Account is locked")
-			}
-		} else {
-			loginAttempts[user.Email] = 1
-		}
-
-		// If the two passwords don't match, return a 401 status.
-		return echo.NewHTTPError(http.StatusUnauthorized, "Invalid password")
-	} else {
-		loginAttempts[user.Email] = 0
-	}
-	
-	// Retrieves user from its email.
-	user, err = auth.users.GetUserByEmail(reqUser.Email)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, "User not found")
-	}
-
-	token, err := createToken(user.Email)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	return c.JSON(http.StatusOK, echo.Map{"token": token})
+    // Deserializes the JSON body and checks its validity.
+    reqUser := new(Credentials)
+    if err := decodeJson(c, &reqUser); err != nil {
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
+    if err := validator.New().Struct(reqUser); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // User exists?
+    user, err := auth.users.GetUserByEmail(reqUser.Email)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // Is user locked?
+    lockedTime, exists := loginLocked[user.Email]
+    if exists {
+        // If locked time has elapsed, unlock the account.
+        t := time.Now()
+        elapsedTime := t.Sub(lockedTime)
+        if elapsedTime.Hours() > lockedTimeInHours {
+            delete(loginLocked, user.Email)
+            delete(loginAttempts, user.Email)
+        } else {
+            return echo.NewHTTPError(http.StatusUnauthorized, "Account is locked")
+        }
+    }
+
+    // Checks the user password is correct.
+    // If a user enters the wrong password too many times, the account will be locked for a number of hours.
+    if err := bcrypt.CompareHashAndPassword([]byte(user.Pwd), []byte(reqUser.Pwd)); err != nil {
+        // Stores the number of attempted logins.
+        count, exists := loginAttempts[user.Email]
+        if exists {
+            loginAttempts[user.Email] = count+1
+            if count >= maxloginAttempts {
+                // Locks the account.
+                loginLocked[user.Email] = time.Now()
+                return echo.NewHTTPError(http.StatusUnauthorized, "Account is locked")
+            }
+        } else {
+            loginAttempts[user.Email] = 1
+        }
+
+        // If the two passwords don't match, return a 401 status.
+        return echo.NewHTTPError(http.StatusUnauthorized, "Invalid password")
+    } else {
+        loginAttempts[user.Email] = 0
+    }
+
+    // Retrieves user from its email.
+    user, err = auth.users.GetUserByEmail(reqUser.Email)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, "User not found")
+    }
+
+    token, err := createToken(user.Email)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    return c.JSON(http.StatusOK, echo.Map{"token": token})
 }
 
 // Creates a JWT token and claims with the expiration time for the given user.
 func createToken(userEmail string) (string, error) {
-	expirationTime := time.Now().Add(accessTokenExpirationTimeInHours*time.Hour)
-
-	// Creates the claims
-	claims := &CustomClaims{
-		Email: userEmail,
-		StandardClaims: jwt.StandardClaims {
-			// JWT expresses expiration time in Unix milliseconds
-			ExpiresAt: expirationTime.Unix(),
-		},
-	}
-
-	// Declares the token with the algorithm used for signing, and the claims.
-	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
-
-	// Signs the token and gets a string version of the token.
-	secret := []byte(jwtSecretKey)
-	tokenString, err := token.SignedString(secret)
-	if err != nil {
-		return "", err
-	}
-
-	return tokenString, nil
+    expirationTime := time.Now().Add(accessTokenExpirationTimeInHours*time.Hour)
+
+    // Creates the claims
+    claims := &CustomClaims{
+        Email: userEmail,
+        StandardClaims: jwt.StandardClaims {
+            // JWT expresses expiration time in Unix milliseconds
+            ExpiresAt: expirationTime.Unix(),
+        },
+    }
+
+    // Declares the token with the algorithm used for signing, and the claims.
+    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+
+    // Signs the token and gets a string version of the token.
+    secret := []byte(jwtSecretKey)
+    tokenString, err := token.SignedString(secret)
+    if err != nil {
+        return "", err
+    }
+
+    return tokenString, nil
 }
 
 // Returns user email from the Echo context.
 // If an error occured, returns the error.
 func GetUserFromContext(c echo.Context) (string, error) {
-	if c.Get("user") == nil {
-		return "", errors.New("user not authenticated")
-	}
+    if c.Get("user") == nil {
+        return "", errors.New("user not authenticated")
+    }
 
-	user := c.Get("user").(*jwt.Token)
-	claims := user.Claims.(*CustomClaims)
+    user := c.Get("user").(*jwt.Token)
+    claims := user.Claims.(*CustomClaims)
 
-	return claims.Email, nil
+    return claims.Email, nil
 }
 
 /*
@@ -194,16 +194,16 @@ func GetUserFromContext(c echo.Context) (string, error) {
 usersGroup.Use(auth.OnlyJoe)  // apply the middleware (to be added in router.go)
 
 func OnlyJoe(next echo.HandlerFunc) echo.HandlerFunc {
-	return func(c echo.Context) error {
-		// Gets user token from context.
+    return func(c echo.Context) error {
+        // Gets user token from context.
         if c.Get("user") == nil {
-			return echo.NewHTTPError(http.StatusUnauthorized, "invalid user token\n")
+            return echo.NewHTTPError(http.StatusUnauthorized, "invalid user token\n")
         }
         user := c.Get("user").(*jwt.Token)
         claims := user.Claims.(*CustomClaims)
         username := claims.Username
         if username != "joe" {
-        	return echo.ErrUnauthorized
+            return echo.ErrUnauthorized
         }
         return next(c)
     }
diff --git a/src/router/helper.go b/src/router/helper.go
index 5ad241bcf148b2cca58459a1365f7f71c51f9c56..dea451098945bb0ff24f565b7e1d6df8d98bd10f 100644
--- a/src/router/helper.go
+++ b/src/router/helper.go
@@ -1,40 +1,40 @@
 package router
 
 import (
-	"encoding/json"
-	"nexus-server/users"
-	"github.com/labstack/echo/v4"
+    "encoding/json"
+    "nexus-server/users"
+    "github.com/labstack/echo/v4"
 )
 
 const (
-	msgInsufficientCaps = "Permission denied: insufficient capabilities"
+    msgInsufficientCaps = "Permission denied: insufficient capabilities"
 )
 
 func jsonMsg(msg string) map[string]interface{} {
-	// The following 2 lines are identical:
-	//return map[string]interface{}{"message": msg}
-	return echo.Map{"message": msg}
+    // The following 2 lines are identical:
+    //return map[string]interface{}{"message": msg}
+    return echo.Map{"message": msg}
 }
 
 // Decodes and validates a json object in the response's body.
 func decodeJson(c echo.Context, object any) error {
-	decoder := json.NewDecoder(c.Request().Body)
-	decoder.DisallowUnknownFields()
-	return decoder.Decode(object)
+    decoder := json.NewDecoder(c.Request().Body)
+    decoder.DisallowUnknownFields()
+    return decoder.Decode(object)
 }
 
 func getLoggedUser(users *users.Users, c echo.Context) (*users.User, error) {
-	// Retrieves user email from context.
-	email, err := GetUserFromContext(c)
-	if err != nil {
-		log.Error("Failed retrieving user info from context: "+err.Error())
-		return nil, err
-	}
-	// Retrieves the user structure
-	user, err := users.GetUserByEmail(email)
-	if err != nil {
-		log.Error("No user matching email "+email+": "+err.Error())
-		return nil, err
-	}
-	return &user, nil
+    // Retrieves user email from context.
+    email, err := GetUserFromContext(c)
+    if err != nil {
+        log.Error("Failed retrieving user info from context: "+err.Error())
+        return nil, err
+    }
+    // Retrieves the user structure
+    user, err := users.GetUserByEmail(email)
+    if err != nil {
+        log.Error("No user matching email "+email+": "+err.Error())
+        return nil, err
+    }
+    return &user, nil
 }
diff --git a/src/router/router.go b/src/router/router.go
index c2b9f6e486d7fc2fa34e9257b9a7c650043aa4db..5402ec0cc4d2ddc89acd5172d64216ab35f523c3 100644
--- a/src/router/router.go
+++ b/src/router/router.go
@@ -1,143 +1,143 @@
 package router
 
 import (
-	"os"
-	"time"
-	"syscall"
-	"context"
-	"strconv"
-	"net/http"
-	"os/signal"
-	"path/filepath"
-	"nexus-server/paths"
-	"nexus-server/users"
-	"nexus-server/logger"
-	"nexus-server/consts"
-	"github.com/labstack/echo/v4"
-	"github.com/labstack/echo/v4/middleware"
+    "os"
+    "time"
+    "syscall"
+    "context"
+    "strconv"
+    "net/http"
+    "os/signal"
+    "path/filepath"
+    "nexus-server/paths"
+    "nexus-server/users"
+    "nexus-server/logger"
+    "nexus-server/consts"
+    "github.com/labstack/echo/v4"
+    "github.com/labstack/echo/v4/middleware"
 )
 
 type Router struct {
-	echo *echo.Echo
-	version *RouterVersion
-	token *RouterToken
-	users *RouterUsers
-	vms *RouterVMs
-	tpl *RouterTemplates
+    echo *echo.Echo
+    version *RouterVersion
+    token *RouterToken
+    users *RouterUsers
+    vms *RouterVMs
+    tpl *RouterTemplates
 }
 
 var log = logger.GetInstance()
 
 func New() *Router {
-	return &Router{
-		echo.New(),
-		NewRouterVersion(),
-		NewRouterToken(),
-		NewRouterUsers(),
-		NewRouterVMs(),
-		NewRouterTemplates()}
+    return &Router{
+        echo.New(),
+        NewRouterVersion(),
+        NewRouterToken(),
+        NewRouterUsers(),
+        NewRouterVMs(),
+        NewRouterTemplates()}
 }
 
 func (router *Router)Start(port int) {
-	auth, err := NewAuth(users.GetUsersInstance())
-	if err != nil {
-		log.Fatal("Server error: "+err.Error())
-	}
-
-	router.echo.HideBanner = true
-	router.echo.Use(middleware.BodyLimit(consts.MaxUploadSize))
-
-	// Login management.
-	router.echo.POST("/login", auth.Login)
-
-	// Version management.
-	router.echo.GET("/version", router.version.GetVersion)
-	
-	// Token management.
-	tokenGroup := router.echo.Group("/token")
-	tokenGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
-	tokenGroup.GET("/refresh", router.token.GetRefreshToken)
-
-	// User management.
-	usersGroup := router.echo.Group("/users")
-	usersGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
+    auth, err := NewAuth(users.GetUsersInstance())
+    if err != nil {
+        log.Fatal("Server error: "+err.Error())
+    }
+
+    router.echo.HideBanner = true
+    router.echo.Use(middleware.BodyLimit(consts.MaxUploadSize))
+
+    // Login management.
+    router.echo.POST("/login", auth.Login)
+
+    // Version management.
+    router.echo.GET("/version", router.version.GetVersion)
+
+    // Token management.
+    tokenGroup := router.echo.Group("/token")
+    tokenGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
+    tokenGroup.GET("/refresh", router.token.GetRefreshToken)
+
+    // User management.
+    usersGroup := router.echo.Group("/users")
+    usersGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
     usersGroup.GET("", router.users.GetUsers)
-	usersGroup.GET("/whoami", router.users.GetLoggedUser)
-	usersGroup.POST("", router.users.CreateUser)
-	usersGroup.DELETE("/:email", router.users.DeleteUserByEmail)
-	usersGroup.PUT("/:email/caps", router.users.SetUserCaps)
-	usersGroup.PUT("/pwd", router.users.SetUserPwd)
-	
-	// VM management.
-	vmsGroup := router.echo.Group("/vms")
-	vmsGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
-	vmsGroup.GET("", router.vms.GetListableVMs)
-	vmsGroup.GET("/attach", router.vms.GetAttachableVMs)
-	vmsGroup.GET("/del", router.vms.GetDeletableVMs)
-	vmsGroup.GET("/start", router.vms.GetStartableVMs)
-	vmsGroup.GET("/stop", router.vms.GetStoppableVMs)
-	vmsGroup.GET("/reboot", router.vms.GetRebootableVMs)
-	vmsGroup.GET("/edit", router.vms.GetEditableVMs)
-	vmsGroup.GET("/editaccess", router.vms.GetEditableVMAccessVMs)
-	vmsGroup.GET("/exportdir", router.vms.GetDirExportableVMs)
-	vmsGroup.GET("/importfiles", router.vms.GetFilesImportableVMs)
-
-	vmsGroup.POST("", router.vms.CreateVM)
-	vmsGroup.DELETE("/:id", router.vms.DeleteVMByID)
-	vmsGroup.PUT("/:id", router.vms.EditVMByID)
-	vmsGroup.PUT("/:id/start", router.vms.StartVM)
-	vmsGroup.PUT("/:id/stop", router.vms.KillVM)
-	vmsGroup.PUT("/:id/shutdown", router.vms.ShutdownVM)
-	vmsGroup.PUT("/:id/reboot", router.vms.RebootVM)
-	vmsGroup.PUT("/:id/access/:email", router.vms.SetVMAccessForUser)
-	vmsGroup.DELETE("/:id/access/:email", router.vms.DeleteVMAccessForUser)
-	vmsGroup.GET("/:id/exportdir", router.vms.ExportVMDir)
-	vmsGroup.POST("/:id/importfiles", router.vms.ImportFilesToVM)
-
-	// Template management.
-	templatesGroup := router.echo.Group("/templates")
-	templatesGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
-	templatesGroup.GET("", router.tpl.GetTemplates)
-	templatesGroup.POST("/vm", router.tpl.CreateTemplateFromVM)
-	templatesGroup.POST("/qcow", router.tpl.CreateTemplateFromQCOW)
-	templatesGroup.GET("/:id/disk", router.tpl.ExportDisk)
-	templatesGroup.DELETE("/:id", router.tpl.DeleteTemplateByID)
-	templatesGroup.PUT("/:id", router.tpl.EditTemplateByID)
-
-	// Starts server in a dedicated goroutine.
-	go func() {
-		pkiDir := paths.GetInstance().NexusPkiDir
-		if err := router.echo.StartTLS(":"+strconv.Itoa(port), filepath.Join(pkiDir, "/server-cert.pem"), filepath.Join(pkiDir, "/server-key.pem")); err != nil {
-			if err != http.ErrServerClosed {
-				log.Fatal("Server error: "+err.Error())
-			} else {
-				log.Info("Shutting down server...")
-			}
-		}
-	}()
-
-	// Wait on dedicated signals.
-	sigs := make(chan os.Signal, 1)
-	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
-
-	for {
-		sig := <-sigs  // blocks on any of the above signals.
-		log.Info("Server caught signal ("+sig.String()+")")
-		// SIGHUP tells the server to reload its configuration.
-		// This is just a placeholder: it does nothing for now.
-		// TODO: reloads users and templates? (very tricky though)
-		if sig == syscall.SIGHUP {
-			log.Info("Reloading server configuration")
-		} else {
-			// Any other signal tells the server to gracefully shutdown.
-			break
-		}
-	}
-
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-	defer cancel()
-	if err := router.echo.Shutdown(ctx); err != nil {
-		log.Fatal("Server shutdown failed: "+err.Error())
-	}
-	log.Info("Server shutdown completed.")
+    usersGroup.GET("/whoami", router.users.GetLoggedUser)
+    usersGroup.POST("", router.users.CreateUser)
+    usersGroup.DELETE("/:email", router.users.DeleteUserByEmail)
+    usersGroup.PUT("/:email/caps", router.users.SetUserCaps)
+    usersGroup.PUT("/pwd", router.users.SetUserPwd)
+
+    // VM management.
+    vmsGroup := router.echo.Group("/vms")
+    vmsGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
+    vmsGroup.GET("", router.vms.GetListableVMs)
+    vmsGroup.GET("/attach", router.vms.GetAttachableVMs)
+    vmsGroup.GET("/del", router.vms.GetDeletableVMs)
+    vmsGroup.GET("/start", router.vms.GetStartableVMs)
+    vmsGroup.GET("/stop", router.vms.GetStoppableVMs)
+    vmsGroup.GET("/reboot", router.vms.GetRebootableVMs)
+    vmsGroup.GET("/edit", router.vms.GetEditableVMs)
+    vmsGroup.GET("/editaccess", router.vms.GetEditableVMAccessVMs)
+    vmsGroup.GET("/exportdir", router.vms.GetDirExportableVMs)
+    vmsGroup.GET("/importfiles", router.vms.GetFilesImportableVMs)
+
+    vmsGroup.POST("", router.vms.CreateVM)
+    vmsGroup.DELETE("/:id", router.vms.DeleteVMByID)
+    vmsGroup.PUT("/:id", router.vms.EditVMByID)
+    vmsGroup.PUT("/:id/start", router.vms.StartVM)
+    vmsGroup.PUT("/:id/stop", router.vms.KillVM)
+    vmsGroup.PUT("/:id/shutdown", router.vms.ShutdownVM)
+    vmsGroup.PUT("/:id/reboot", router.vms.RebootVM)
+    vmsGroup.PUT("/:id/access/:email", router.vms.SetVMAccessForUser)
+    vmsGroup.DELETE("/:id/access/:email", router.vms.DeleteVMAccessForUser)
+    vmsGroup.GET("/:id/exportdir", router.vms.ExportVMDir)
+    vmsGroup.POST("/:id/importfiles", router.vms.ImportFilesToVM)
+
+    // Template management.
+    templatesGroup := router.echo.Group("/templates")
+    templatesGroup.Use(middleware.JWTWithConfig(auth.GetTokenAccess()))
+    templatesGroup.GET("", router.tpl.GetTemplates)
+    templatesGroup.POST("/vm", router.tpl.CreateTemplateFromVM)
+    templatesGroup.POST("/qcow", router.tpl.CreateTemplateFromQCOW)
+    templatesGroup.GET("/:id/disk", router.tpl.ExportDisk)
+    templatesGroup.DELETE("/:id", router.tpl.DeleteTemplateByID)
+    templatesGroup.PUT("/:id", router.tpl.EditTemplateByID)
+
+    // Starts server in a dedicated goroutine.
+    go func() {
+        pkiDir := paths.GetInstance().NexusPkiDir
+        if err := router.echo.StartTLS(":"+strconv.Itoa(port), filepath.Join(pkiDir, "/server-cert.pem"), filepath.Join(pkiDir, "/server-key.pem")); err != nil {
+            if err != http.ErrServerClosed {
+                log.Fatal("Server error: "+err.Error())
+            } else {
+                log.Info("Shutting down server...")
+            }
+        }
+    }()
+
+    // Wait on dedicated signals.
+    sigs := make(chan os.Signal, 1)
+    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
+
+    for {
+        sig := <-sigs  // blocks on any of the above signals.
+        log.Info("Server caught signal ("+sig.String()+")")
+        // SIGHUP tells the server to reload its configuration.
+        // This is just a placeholder: it does nothing for now.
+        // TODO: reloads users and templates? (very tricky though)
+        if sig == syscall.SIGHUP {
+            log.Info("Reloading server configuration")
+        } else {
+            // Any other signal tells the server to gracefully shutdown.
+            break
+        }
+    }
+
+    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+    defer cancel()
+    if err := router.echo.Shutdown(ctx); err != nil {
+        log.Fatal("Server shutdown failed: "+err.Error())
+    }
+    log.Info("Server shutdown completed.")
 }
diff --git a/src/router/routerTemplates.go b/src/router/routerTemplates.go
index 33c7d4c9f80e31eaaf9f5fc4679edc128dbed83a..ac751c6182ac98e137cdc758095e4babb8659b44 100644
--- a/src/router/routerTemplates.go
+++ b/src/router/routerTemplates.go
@@ -1,28 +1,28 @@
 package router
 
 import (
-	"io"
-	"os"
-	"net/http"
-	"path/filepath"
-	"nexus-server/vms"
-	"nexus-server/caps"
-	"nexus-server/paths"
-	"nexus-server/users"
+    "io"
+    "os"
+    "net/http"
+    "path/filepath"
+    "nexus-server/vms"
+    "nexus-server/caps"
+    "nexus-server/paths"
+    "nexus-server/users"
     "github.com/labstack/echo/v4"
-	"github.com/google/uuid"
+    "github.com/google/uuid"
 )
 
 type (
-	RouterTemplates struct {
-		users *users.Users
-		tpl *vms.Templates
-		vms *vms.VMs
-	}
+    RouterTemplates struct {
+        users *users.Users
+        tpl *vms.Templates
+        vms *vms.VMs
+    }
 )
 
 func NewRouterTemplates() *RouterTemplates {
-	return &RouterTemplates{ users: users.GetUsersInstance(), tpl: vms.GetTemplatesInstance(), vms: vms.GetVMsInstance() }
+    return &RouterTemplates{ users: users.GetUsersInstance(), tpl: vms.GetTemplatesInstance(), vms: vms.GetVMsInstance() }
 }
 
 // Returns templates that can be listed.
@@ -31,85 +31,85 @@ func NewRouterTemplates() *RouterTemplates {
 // CAP_TPL_LIST: only templates owned by the user as well as public templates can be listed.
 // curl --cacert ca.pem -X GET https://localhost:1077/templates -H "Authorization: Bearer <AccessToken>"
 func (r *RouterTemplates)GetTemplates(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// If the logged user has CAP_TPL_LIST_ANY, lists all templates.
-	if user.HasCapability(caps.CAP_TPL_LIST_ANY) {
-		// Returns all templates
-		return c.JSONPretty(http.StatusOK, r.tpl.GetTemplates(func(t vms.Template) bool { return true }), "    ")
-	} else if user.HasCapability(caps.CAP_TPL_LIST) {
-		// Returns templates owned by the logged user and public templates.
-		return c.JSONPretty(http.StatusOK,
-			r.tpl.GetTemplates(func(t vms.Template) bool {
-				return t.Owner == user.Email || t.IsPublic()
-			}), "    ")
-	} else {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // If the logged user has CAP_TPL_LIST_ANY, lists all templates.
+    if user.HasCapability(caps.CAP_TPL_LIST_ANY) {
+        // Returns all templates
+        return c.JSONPretty(http.StatusOK, r.tpl.GetTemplates(func(t vms.Template) bool { return true }), "    ")
+    } else if user.HasCapability(caps.CAP_TPL_LIST) {
+        // Returns templates owned by the logged user and public templates.
+        return c.JSONPretty(http.StatusOK,
+            r.tpl.GetTemplates(func(t vms.Template) bool {
+                return t.Owner == user.Email || t.IsPublic()
+            }), "    ")
+    } else {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
 }
 
 // Creates a template from a VM.
 // Requires CAP_TPL_CREATE.
 // curl --cacert ca.pem -X POST https://localhost:1077/templates/vm -H 'Content-Type: application/json' -d '{"vmID":"e41f3556-ca24-4658-bd79-8c85bd6bff59","name":"Xubuntu_22.04","access":"public"}' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterTemplates)CreateTemplateFromVM(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	if !user.HasCapability(caps.CAP_TPL_CREATE) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
-
-	// Deserializes and validates the client's parameters.
-	type Parameters struct {
-		VMID uuid.UUID      `json:"vmID" validate:"required"`
-		Name string         `json:"name" validate:"required,min=2"`
-		Access string       `json:"access" validate:"required,min=4"`
-	}
-	p := new(Parameters)
-	if err := decodeJson(c, &p); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Retrieves the VM from its vmID and checks the logged user can access it.
-	vm, err := r.vms.GetVM(p.VMID)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	// If the user isn't the VM's owner, checks that the required capabilities are met:
-	// either VM_LIST_ANY or VM_LIST in the VM access
-	if !vm.IsOwner(user.Email) {
-		// Check the user has the required capabilities: either VM_LIST_ANY or VM_LIST in the VM access
-		if !user.HasCapability(caps.CAP_VM_LIST_ANY) {
-			userCaps, exists := vm.Access[user.Email]
-			if !exists {
-				return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-			}
-
-			_, hasAccess := userCaps[caps.CAP_VM_LIST]
-			if !hasAccess {
-				return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-			}
-		}
-	}
-
-	// Creates a new template from the client's parameters.
-	template, err := vms.NewTemplateFromVM(p.Name, user.Email, p.Access, &vm)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Adds the template.
-	if err = r.tpl.AddTemplate(template); err != nil {
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    if !user.HasCapability(caps.CAP_TPL_CREATE) {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
+
+    // Deserializes and validates the client's parameters.
+    type Parameters struct {
+        VMID uuid.UUID      `json:"vmID" validate:"required"`
+        Name string         `json:"name" validate:"required,min=2"`
+        Access string       `json:"access" validate:"required,min=4"`
+    }
+    p := new(Parameters)
+    if err := decodeJson(c, &p); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Retrieves the VM from its vmID and checks the logged user can access it.
+    vm, err := r.vms.GetVM(p.VMID)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    // If the user isn't the VM's owner, checks that the required capabilities are met:
+    // either VM_LIST_ANY or VM_LIST in the VM access
+    if !vm.IsOwner(user.Email) {
+        // Check the user has the required capabilities: either VM_LIST_ANY or VM_LIST in the VM access
+        if !user.HasCapability(caps.CAP_VM_LIST_ANY) {
+            userCaps, exists := vm.Access[user.Email]
+            if !exists {
+                return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+            }
+
+            _, hasAccess := userCaps[caps.CAP_VM_LIST]
+            if !hasAccess {
+                return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+            }
+        }
+    }
+
+    // Creates a new template from the client's parameters.
+    template, err := vms.NewTemplateFromVM(p.Name, user.Email, p.Access, &vm)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Adds the template.
+    if err = r.tpl.AddTemplate(template); err != nil {
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
 
     return c.JSONPretty(http.StatusCreated, template, "    ")
 }
@@ -126,62 +126,62 @@ func (r *RouterTemplates)CreateTemplateFromVM(c echo.Context) error {
 // The upload uses exactly the code recipe desribed here:
 // https://echo.labstack.com/guide/#form-multipartform-data
 func (r *RouterTemplates)CreateTemplateFromQCOW(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	if !user.HasCapability(caps.CAP_TPL_CREATE) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
-
-	name := c.FormValue("name")
-	access := c.FormValue("access")
-	if err = vms.ValidateTemplateAccess(access); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	qcowFile, err := c.FormFile("qcow")
-	if err != nil {
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
-	src, err := qcowFile.Open()
-	if err != nil {
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
-	defer src.Close()
-
-	tmpDir := paths.GetInstance().TmpDir
-	uuid, err := uuid.NewRandom()
-	if err != nil {
-		log.Error("Failed creating random UUID: "+err.Error())
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
-	uploadedFile := filepath.Join(tmpDir, "upload_"+uuid.String()+".qcow")
-	dst, err := os.Create(uploadedFile)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
-	defer dst.Close()
-	defer os.Remove(uploadedFile)
-
-	if _, err = io.Copy(dst, src); err != nil {
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
-
-	// Creates a new template
-	template, err := vms.NewTemplateFromQCOW(name, user.Email, access, uploadedFile)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Adds the template.
-	if err = r.tpl.AddTemplate(template); err != nil {
-		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-	}
-
-	return c.JSONPretty(http.StatusCreated, template, "    ")
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    if !user.HasCapability(caps.CAP_TPL_CREATE) {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
+
+    name := c.FormValue("name")
+    access := c.FormValue("access")
+    if err = vms.ValidateTemplateAccess(access); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    qcowFile, err := c.FormFile("qcow")
+    if err != nil {
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
+    src, err := qcowFile.Open()
+    if err != nil {
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
+    defer src.Close()
+
+    tmpDir := paths.GetInstance().TmpDir
+    uuid, err := uuid.NewRandom()
+    if err != nil {
+        log.Error("Failed creating random UUID: "+err.Error())
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
+    uploadedFile := filepath.Join(tmpDir, "upload_"+uuid.String()+".qcow")
+    dst, err := os.Create(uploadedFile)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
+    defer dst.Close()
+    defer os.Remove(uploadedFile)
+
+    if _, err = io.Copy(dst, src); err != nil {
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
+
+    // Creates a new template
+    template, err := vms.NewTemplateFromQCOW(name, user.Email, access, uploadedFile)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Adds the template.
+    if err = r.tpl.AddTemplate(template); err != nil {
+        return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusCreated, template, "    ")
 }
 
 // Deletes a template based on its ID.
@@ -191,38 +191,38 @@ func (r *RouterTemplates)CreateTemplateFromQCOW(c echo.Context) error {
 // Remark: a template can only be deleted if no VM references it!
 // curl --cacert ca.pem -X DELETE https://localhost:1077/templates/4913a2bb-edfe-4dfe-af53-38197a44523b -H "Authorization: Bearer <AccessToken>"
 func (r *RouterTemplates)DeleteTemplateByID(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// Retrieves template ID.
-	tplID, err := uuid.Parse(c.Param("id"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	if user.HasCapability(caps.CAP_TPL_DESTROY_ANY) {
-		if err := r.tpl.DeleteTemplate(tplID, r.vms); err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	} else if user.HasCapability(caps.CAP_TPL_DESTROY) {
-		template, err := r.tpl.GetTemplate(tplID)
-		if err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-
-		if template.Owner == user.Email {
-			if err := r.tpl.DeleteTemplate(tplID, r.vms); err != nil {
-				return echo.NewHTTPError(http.StatusNotFound, err.Error())
-			}
-			return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-		}
-	}
-	
-	return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // Retrieves template ID.
+    tplID, err := uuid.Parse(c.Param("id"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    if user.HasCapability(caps.CAP_TPL_DESTROY_ANY) {
+        if err := r.tpl.DeleteTemplate(tplID, r.vms); err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    } else if user.HasCapability(caps.CAP_TPL_DESTROY) {
+        template, err := r.tpl.GetTemplate(tplID)
+        if err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+
+        if template.Owner == user.Email {
+            if err := r.tpl.DeleteTemplate(tplID, r.vms); err != nil {
+                return echo.NewHTTPError(http.StatusNotFound, err.Error())
+            }
+            return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+        }
+    }
+
+    return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
 }
 
 // Edit a template based on its ID.
@@ -231,52 +231,52 @@ func (r *RouterTemplates)DeleteTemplateByID(c echo.Context) error {
 // CAP_TPL_EDIT: only a template owned by the user can be edited.
 // curl --cacert ca.pem -X PUT https://localhost:1077/templates/4913a2bb-edfe-4dfe-af53-38197a44523b -H "Authorization: Bearer <AccessToken>"
 func (r *RouterTemplates)EditTemplateByID(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// Retrieves template ID.
-	tplID, err := uuid.Parse(c.Param("id"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Deserializes and validates the client's parameters.
-	// Given these parameters are optional, we can't use a validator on them.
-	// Validation is performed in templates.EditTemplate() instead.
-	type Parameters struct {
-		Name   string          `json:"name"`
-		Access string          `json:"access"`
-	}
-	p := new(Parameters)
-
-	if user.HasCapability(caps.CAP_TPL_EDIT_ANY) {
-		if err := decodeJson(c, &p); err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-		}
-		if err := r.tpl.EditTemplate(tplID, p.Name, p.Access); err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	} else if user.HasCapability(caps.CAP_TPL_EDIT) {
-		template, err := r.tpl.GetTemplate(tplID)
-		if err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		if template.Owner == user.Email {
-			if err := decodeJson(c, &p); err != nil {
-				return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-			}
-			if err := r.tpl.EditTemplate(tplID, p.Name, p.Access); err != nil {
-				return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-			}
-			return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-		}
-	}
-
-	return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // Retrieves template ID.
+    tplID, err := uuid.Parse(c.Param("id"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Deserializes and validates the client's parameters.
+    // Given these parameters are optional, we can't use a validator on them.
+    // Validation is performed in templates.EditTemplate() instead.
+    type Parameters struct {
+        Name   string          `json:"name"`
+        Access string          `json:"access"`
+    }
+    p := new(Parameters)
+
+    if user.HasCapability(caps.CAP_TPL_EDIT_ANY) {
+        if err := decodeJson(c, &p); err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+        }
+        if err := r.tpl.EditTemplate(tplID, p.Name, p.Access); err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    } else if user.HasCapability(caps.CAP_TPL_EDIT) {
+        template, err := r.tpl.GetTemplate(tplID)
+        if err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        if template.Owner == user.Email {
+            if err := decodeJson(c, &p); err != nil {
+                return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+            }
+            if err := r.tpl.EditTemplate(tplID, p.Name, p.Access); err != nil {
+                return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+            }
+            return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+        }
+    }
+
+    return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
 }
 
 // Exports a template's disk image.
@@ -285,34 +285,34 @@ func (r *RouterTemplates)EditTemplateByID(c echo.Context) error {
 // CAP_TPL_READFS: only a template owned by the user can have its disk exported.
 // curl --cacert ca.pem -X GET https://localhost:1077/templates/4913a2bb-edfe-4dfe-af53-38197a44523b/disk -H "Authorization: Bearer <AccessToken>" --output disk.qcow
 func (r *RouterTemplates)ExportDisk(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// Retrieves template ID.
-	tplID, err := uuid.Parse(c.Param("id"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	if user.HasCapability(caps.CAP_TPL_READFS_ANY) {
-		t, err := r.tpl.GetTemplate(tplID)
-		if err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		return c.File(t.GetTemplateDiskPath())
-
-	} else if user.HasCapability(caps.CAP_TPL_READFS) {
-		t, err := r.tpl.GetTemplate(tplID)
-		if err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		if t.IsPublic() || t.Owner == user.Email {
-			return c.File(t.GetTemplateDiskPath())
-		}
-	}
-
-	return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // Retrieves template ID.
+    tplID, err := uuid.Parse(c.Param("id"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    if user.HasCapability(caps.CAP_TPL_READFS_ANY) {
+        t, err := r.tpl.GetTemplate(tplID)
+        if err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        return c.File(t.GetTemplateDiskPath())
+
+    } else if user.HasCapability(caps.CAP_TPL_READFS) {
+        t, err := r.tpl.GetTemplate(tplID)
+        if err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        if t.IsPublic() || t.Owner == user.Email {
+            return c.File(t.GetTemplateDiskPath())
+        }
+    }
+
+    return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
 }
diff --git a/src/router/routerToken.go b/src/router/routerToken.go
index 995ed86e5fb905812243ee267c02dd53d59955be..99d4398eda6c8d881bb0b45804ec0667687276e2 100644
--- a/src/router/routerToken.go
+++ b/src/router/routerToken.go
@@ -1,32 +1,32 @@
 package router
 
 import (
-	"net/http"
-	"nexus-server/users"
+    "net/http"
+    "nexus-server/users"
     "github.com/labstack/echo/v4"
 )
 
 type RouterToken struct {
-	users *users.Users
+    users *users.Users
 }
 
 func NewRouterToken() *RouterToken {
-	return &RouterToken{ users.GetUsersInstance() }
+    return &RouterToken{ users.GetUsersInstance() }
 }
 
 // Obtains a new access token.
 // curl --cacert ca.pem -X GET http://localhost:1077/token/refresh -H "Authorization: Bearer <AccessToken>"
 func (r *RouterToken)GetRefreshToken(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
 
-	token, err := createToken(user.Email)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
+    token, err := createToken(user.Email)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
 
-	return c.JSON(http.StatusOK, echo.Map{"token": token})
+    return c.JSON(http.StatusOK, echo.Map{"token": token})
 }
diff --git a/src/router/routerUsers.go b/src/router/routerUsers.go
index ef618d14d186820ca75be62b412386bebe429fc4..cd713b57b9917812f010ab58f35f1ba2110689f8 100644
--- a/src/router/routerUsers.go
+++ b/src/router/routerUsers.go
@@ -1,197 +1,197 @@
 package router
 
 import (
-	"net/http"
-	"nexus-server/caps"
-	"nexus-server/users"
-	"nexus-server/utils"
-	"github.com/labstack/echo/v4"
-	"github.com/go-playground/validator/v10"
+    "net/http"
+    "nexus-server/caps"
+    "nexus-server/users"
+    "nexus-server/utils"
+    "github.com/labstack/echo/v4"
+    "github.com/go-playground/validator/v10"
 )
 
 type RouterUsers struct {
-	users *users.Users
+    users *users.Users
 }
 
 func NewRouterUsers() *RouterUsers {
-	return &RouterUsers{users.GetUsersInstance()}
+    return &RouterUsers{users.GetUsersInstance()}
 }
 
 // Lists users.
 // Requires CAP_USER_LIST.
 // curl --cacert ca.pem -X GET http://localhost:1077/users -H "Authorization: Bearer <AccessToken>"
 func (r *RouterUsers) GetUsers(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	if !user.HasCapability(caps.CAP_USER_LIST) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
-
-	list := []users.UserWithoutPwd{}
-	for _, u := range r.users.GetUsers() {
-		user := users.UserWithoutPwd{u.Email, u.FirstName, u.LastName, u.Caps}
-		list = append(list, user)
-	}
-
-	return c.JSONPretty(http.StatusOK, list, "    ")
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    if !user.HasCapability(caps.CAP_USER_LIST) {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
+
+    list := []users.UserWithoutPwd{}
+    for _, u := range r.users.GetUsers() {
+        user := users.UserWithoutPwd{u.Email, u.FirstName, u.LastName, u.Caps}
+        list = append(list, user)
+    }
+
+    return c.JSONPretty(http.StatusOK, list, "    ")
 }
 
 // Retrieves the logged (authententicated) user.
 // curl --cacert ca.pem -X GET http://localhost:1077/users/me -H "Authorization: Bearer <AccessToken>"
 func (r *RouterUsers) GetLoggedUser(c echo.Context) error {
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
 
-	return c.JSONPretty(http.StatusOK, user, "    ")
+    return c.JSONPretty(http.StatusOK, user, "    ")
 }
 
 // Deletes a user by its ID.
 // Requires CAP_USER_DESTROY.
 // curl --cacert ca.pem -X DELETE http://localhost:1077/users/janedoes@nexus.org -H "Authorization: Bearer <AccessToken>"
 func (r *RouterUsers) DeleteUserByEmail(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	if !user.HasCapability(caps.CAP_USER_DESTROY) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
-
-	userToDelete, err := r.users.GetUserByEmail(c.Param("email"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	if err = r.users.DeleteUserByEmail(userToDelete.Email); err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    if !user.HasCapability(caps.CAP_USER_DESTROY) {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
+
+    userToDelete, err := r.users.GetUserByEmail(c.Param("email"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    if err = r.users.DeleteUserByEmail(userToDelete.Email); err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
 }
 
 // Creates a user.
 // Requires CAP_USER_CREATE.
 // curl --cacert ca.pem -X POST http://localhost:1077/users -H 'Content-Type: application/json' -d '{"email":"johndoe@nexus.org","firstName":"John","lastName":"Doe","pwd":"pipomolo","caps":{"USER_LIST":1,"VM_CREATE":1, "VM_SET_ACCESS":1}}' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterUsers) CreateUser(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
 
-	if !user.HasCapability(caps.CAP_USER_CREATE) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
+    if !user.HasCapability(caps.CAP_USER_CREATE) {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
 
-	// The client's parameters match exactly the User structure, thus
-	// creates a new empty user to deserialize the client's parameters into.
-	newUser := users.NewEmptyUser()
+    // The client's parameters match exactly the User structure, thus
+    // creates a new empty user to deserialize the client's parameters into.
+    newUser := users.NewEmptyUser()
 
-	// Deserializes the JSON body and checks its validity.
-	if err := decodeJson(c, &newUser); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
+    // Deserializes the JSON body and checks its validity.
+    if err := decodeJson(c, &newUser); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
 
-	if err = newUser.Validate(); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
+    if err = newUser.Validate(); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
 
-	newUser.Pwd = utils.HashPassword(newUser.Pwd)
+    newUser.Pwd = utils.HashPassword(newUser.Pwd)
 
-	// Adds user and updates users file.
-	if err = r.users.AddUser(newUser); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
+    // Adds user and updates users file.
+    if err = r.users.AddUser(newUser); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
 
-	return c.JSONPretty(http.StatusCreated, newUser, "    ")
+    return c.JSONPretty(http.StatusCreated, newUser, "    ")
 }
 
 // Update a user's capabilities.
 // Requires CAP_USER_SET_CAPS.
 // curl --cacert ca.pem -X PUT http://localhost:1077/users/janedoes@nexus.org/caps -H 'Content-Type: application/json' -d '{"caps":{"USER_LIST":1,"VM_CREATE":1, "VM_SET_ACCESS":1}}' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterUsers) SetUserCaps(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	if !user.HasCapability(caps.CAP_USER_SET_CAPS) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
-
-	// Deserializes and validates the client's parameters.
-	type Parameters struct {
-		Caps caps.Capabilities
-	}
-	params := &Parameters{make(caps.Capabilities)}
-
-	if err := decodeJson(c, &params); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Checks capabilities are valid.
-	if err := caps.ValidateUserCaps(params.Caps); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Retrieves the user for which the capabilities must be udpated.
-	userToUpdate, err := r.users.GetUserByEmail(c.Param("email"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	// Updates the user's capabilities.
-	userToUpdate.Caps = params.Caps
-
-	// Updates user and saves the new user file.
-	if err = r.users.UpdateUser(&userToUpdate); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    if !user.HasCapability(caps.CAP_USER_SET_CAPS) {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
+
+    // Deserializes and validates the client's parameters.
+    type Parameters struct {
+        Caps caps.Capabilities
+    }
+    params := &Parameters{make(caps.Capabilities)}
+
+    if err := decodeJson(c, &params); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Checks capabilities are valid.
+    if err := caps.ValidateUserCaps(params.Caps); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Retrieves the user for which the capabilities must be udpated.
+    userToUpdate, err := r.users.GetUserByEmail(c.Param("email"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    // Updates the user's capabilities.
+    userToUpdate.Caps = params.Caps
+
+    // Updates user and saves the new user file.
+    if err = r.users.UpdateUser(&userToUpdate); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
 }
 
 // Update the logged user's password.
 // curl --cacert ca.pem -X PUT http://localhost:1077/users/pwd -H 'Content-Type: application/json' -d '{"pwd": "new_password"}' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterUsers) SetUserPwd(c echo.Context) error {
-	// Deserializes the client's parameters.
-	type Parameters struct {
-		Pwd string `json:"pwd" validate:"required,min=8"`
-	}
-	params := &Parameters{}
-
-	// Deserializes the JSON body and checks its validity.
-	if err := decodeJson(c, &params); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Checks the new password is valid.
-	if err := validator.New().Struct(params); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Retrieves the logged user for which the password must be udpated.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// Hashes and udpates the user's password.
-	user.Pwd = utils.HashPassword(params.Pwd)
-
-	// Updates user and saves the new user file.
-	if err = r.users.UpdateUser(user); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    // Deserializes the client's parameters.
+    type Parameters struct {
+        Pwd string `json:"pwd" validate:"required,min=8"`
+    }
+    params := &Parameters{}
+
+    // Deserializes the JSON body and checks its validity.
+    if err := decodeJson(c, &params); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Checks the new password is valid.
+    if err := validator.New().Struct(params); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Retrieves the logged user for which the password must be udpated.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // Hashes and udpates the user's password.
+    user.Pwd = utils.HashPassword(params.Pwd)
+
+    // Updates user and saves the new user file.
+    if err = r.users.UpdateUser(user); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
 }
diff --git a/src/router/routerVMs.go b/src/router/routerVMs.go
index 0fb2cd992bf72aed64ec1f4d0eaa5f695de8a9b0..964d35a3151654a8c8be43ff3b8247e443058293 100644
--- a/src/router/routerVMs.go
+++ b/src/router/routerVMs.go
@@ -1,31 +1,31 @@
 package router
 
 import (
-	"io"
-	"os"
-	"net/http"
-	"path/filepath"
-	"nexus-server/vms"
-	"nexus-server/caps"	
-	"nexus-server/users"
-	"nexus-server/paths"
-	"github.com/google/uuid"
-	"github.com/labstack/echo/v4"
-	"github.com/go-playground/validator/v10"
+    "io"
+    "os"
+    "net/http"
+    "path/filepath"
+    "nexus-server/vms"
+    "nexus-server/caps"
+    "nexus-server/users"
+    "nexus-server/paths"
+    "github.com/google/uuid"
+    "github.com/labstack/echo/v4"
+    "github.com/go-playground/validator/v10"
 )
 
 type (
-	RouterVMs struct {
-		users *users.Users
-		vms *vms.VMs
-	}
+    RouterVMs struct {
+        users *users.Users
+        vms *vms.VMs
+    }
 
-	vmActionFn func(c echo.Context, vm *vms.VM) error
-	vmsListableFn func(c echo.Context, vm *vms.VM) error
+    vmActionFn func(c echo.Context, vm *vms.VM) error
+    vmsListableFn func(c echo.Context, vm *vms.VM) error
 )
 
 func NewRouterVMs() *RouterVMs {
-	return &RouterVMs{ users: users.GetUsersInstance(), vms: vms.GetVMsInstance() }
+    return &RouterVMs{ users: users.GetUsersInstance(), vms: vms.GetVMsInstance() }
 }
 
 // Returns VMs that can be listed.
@@ -34,9 +34,9 @@ func NewRouterVMs() *RouterVMs {
 // VM access cap: CAP_VM_LIST: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetListableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm vms.VM) bool {
-		return true
-	})
+    return r.performVMsList(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm vms.VM) bool {
+        return true
+    })
 }
 
 // Returns VMs that are running and that can be attached to.
@@ -45,9 +45,9 @@ func (r *RouterVMs)GetListableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_LIST: returns all running VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/attach -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetAttachableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm vms.VM) bool {
-		return vm.IsRunning()
-	})
+    return r.performVMsList(c, caps.CAP_VM_LIST_ANY, caps.CAP_VM_LIST, func(vm vms.VM) bool {
+        return vm.IsRunning()
+    })
 }
 
 // Returns VMs that are stopped and that can be deleted.
@@ -56,9 +56,9 @@ func (r *RouterVMs)GetAttachableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_DESTROY: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/del -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetDeletableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(vm vms.VM) bool {
-		return !vm.IsRunning()
-	})
+    return r.performVMsList(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(vm vms.VM) bool {
+        return !vm.IsRunning()
+    })
 }
 
 // Returns VMs that are stopped and that can be started.
@@ -67,9 +67,9 @@ func (r *RouterVMs)GetDeletableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_START: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/start -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetStartableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(vm vms.VM) bool {
-		return !vm.IsRunning()
-	})
+    return r.performVMsList(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(vm vms.VM) bool {
+        return !vm.IsRunning()
+    })
 }
 
 // Returns VMs that are running and that can be stopped.
@@ -78,9 +78,9 @@ func (r *RouterVMs)GetStartableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_STOP: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/stop -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetStoppableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(vm vms.VM) bool {
-		return vm.IsRunning()
-	})
+    return r.performVMsList(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(vm vms.VM) bool {
+        return vm.IsRunning()
+    })
 }
 
 // Returns VMs that are running and that can be rebooted.
@@ -89,9 +89,9 @@ func (r *RouterVMs)GetStoppableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_REBOOT: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/reboot -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetRebootableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(vm vms.VM) bool {
-		return vm.IsRunning()
-	})
+    return r.performVMsList(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(vm vms.VM) bool {
+        return vm.IsRunning()
+    })
 }
 
 // Returns VMs that can be edited.
@@ -100,9 +100,9 @@ func (r *RouterVMs)GetRebootableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_EDIT: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/edit -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetEditableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(vm vms.VM) bool {
-		return true
-	})
+    return r.performVMsList(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(vm vms.VM) bool {
+        return true
+    })
 }
 
 // Returns VMs that can have their access set or deleted.
@@ -111,33 +111,33 @@ func (r *RouterVMs)GetEditableVMs(c echo.Context) error {
 // VM access cap: CAP_VM_SET_ACCESS
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/editaccess -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(
-		func(vm vms.VM) bool {
-			// First, checks if the user is the VM's owner
-			if vm.IsOwner(user.Email) {
-				return true
-			} else {
-				// Then, checks that user has CAP_VM_SET_ACCESS and also that
-				// VM access has CAP_VM_SET_ACCESS set for the user
-				if user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-					capabilities, exists := vm.Access[user.Email]
-					if exists {
-						_, visible := capabilities[caps.CAP_VM_SET_ACCESS]
-						return visible
-					} else {
-						return false
-					}
-				} else {
-					return false
-				}
-			}
-		  }), "    ")
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(
+        func(vm vms.VM) bool {
+            // First, checks if the user is the VM's owner
+            if vm.IsOwner(user.Email) {
+                return true
+            } else {
+                // Then, checks that user has CAP_VM_SET_ACCESS and also that
+                // VM access has CAP_VM_SET_ACCESS set for the user
+                if user.HasCapability(caps.CAP_VM_SET_ACCESS) {
+                    capabilities, exists := vm.Access[user.Email]
+                    if exists {
+                        _, visible := capabilities[caps.CAP_VM_SET_ACCESS]
+                        return visible
+                    } else {
+                        return false
+                    }
+                } else {
+                    return false
+                }
+            }
+          }), "    ")
 }
 
 // Returns VMs that can have a directory exported.
@@ -146,9 +146,9 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
 // VM access cap: VM_READFS: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/exportdir -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetDirExportableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(vm vms.VM) bool {
-		return true
-	})
+    return r.performVMsList(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(vm vms.VM) bool {
+        return true
+    })
 }
 
 // Returns VMs that can have files imported (i.e. copied) into their filesystem.
@@ -157,9 +157,9 @@ func (r *RouterVMs)GetDirExportableVMs(c echo.Context) error {
 // VM access cap: VM_WRITEFS: returns all VMs with this cap for the logged user.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/importfiles -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetFilesImportableVMs(c echo.Context) error {
-	return r.performVMsList(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(vm vms.VM) bool {
-		return true
-	})
+    return r.performVMsList(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(vm vms.VM) bool {
+        return true
+    })
 }
 
 // Creates a VM.
@@ -167,40 +167,40 @@ func (r *RouterVMs)GetFilesImportableVMs(c echo.Context) error {
 // User cap: CAP_VM_CREATE.
 // curl --cacert ca.pem -X POST https://localhost:1077/vms -H 'Content-Type: application/json' -d '{"name":"Systems Programming 2022","cpus":2,"ram":4096,"nic":"none","template":"Xubuntu_22.04"}' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)CreateVM(c echo.Context) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	if !user.HasCapability(caps.CAP_VM_CREATE) {
-		return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-	}
-
-	// Deserializes and validates client's parameters.
-	type Parameters struct {
-		Name string           `json:"name"       validate:"required,min=4,max=256"`
-		Cpus int              `json:"cpus"       validate:"required,gte=1,lte=16"`
-		Ram int               `json:"ram"        validate:"required,gte=512,lte=32768"`  // in MB
-		Nic vms.NicType       `json:"nic"        validate:"required"`  // "none" or "user"
-		TemplateID uuid.UUID  `json:"templateID" validate:"required"`
-	}
-	p := new(Parameters)
-	if err := decodeJson(c, &p); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Creates a new VM from the client's parameters.
-	vm, err := vms.NewVM(user.Email, p.Name, p.Cpus, p.Ram, p.Nic, p.TemplateID, user.Email)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	if err = r.vms.AddVM(vm); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	return c.JSONPretty(http.StatusCreated, vm.SerializeToNetwork(), "    ")
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    if !user.HasCapability(caps.CAP_VM_CREATE) {
+        return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+    }
+
+    // Deserializes and validates client's parameters.
+    type Parameters struct {
+        Name string           `json:"name"       validate:"required,min=4,max=256"`
+        Cpus int              `json:"cpus"       validate:"required,gte=1,lte=16"`
+        Ram int               `json:"ram"        validate:"required,gte=512,lte=32768"`  // in MB
+        Nic vms.NicType       `json:"nic"        validate:"required"`  // "none" or "user"
+        TemplateID uuid.UUID  `json:"templateID" validate:"required"`
+    }
+    p := new(Parameters)
+    if err := decodeJson(c, &p); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Creates a new VM from the client's parameters.
+    vm, err := vms.NewVM(user.Email, p.Name, p.Cpus, p.Ram, p.Nic, p.TemplateID, user.Email)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    if err = r.vms.AddVM(vm); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusCreated, vm.SerializeToNetwork(), "    ")
 }
 
 // Deletes a VM based on its ID.
@@ -209,12 +209,12 @@ func (r *RouterVMs)CreateVM(c echo.Context) error {
 // VM access cap: CAP_VM_DESTROY: any of the VMs with this cap for the logged user can be deleted.
 // curl --cacert ca.pem -X DELETE https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59 -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)DeleteVMByID(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(c echo.Context, vm *vms.VM) error {
-		if err := r.vms.DeleteVM(vm.ID); err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	})
+    return r.performVMAction(c, caps.CAP_VM_DESTROY_ANY, caps.CAP_VM_DESTROY, func(c echo.Context, vm *vms.VM) error {
+        if err := r.vms.DeleteVM(vm.ID); err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    })
 }
 
 // Starts a VM based on its ID.
@@ -223,13 +223,13 @@ func (r *RouterVMs)DeleteVMByID(c echo.Context) error {
 // VM access cap: CAP_VM_START: any of the VMs with this cap for the logged user can be started.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/start -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)StartVM(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(c echo.Context, vm *vms.VM) error {
-		_, _, err := r.vms.StartVM(vm.ID)
-		if err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	})
+    return r.performVMAction(c, caps.CAP_VM_START_ANY, caps.CAP_VM_START, func(c echo.Context, vm *vms.VM) error {
+        _, _, err := r.vms.StartVM(vm.ID)
+        if err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    })
 }
 
 // Kills a VM based on its ID.
@@ -238,12 +238,12 @@ func (r *RouterVMs)StartVM(c echo.Context) error {
 // VM access cap: CAP_VM_STOP: any of the VMs with this cap for the logged user can be killed.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/stop -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)KillVM(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
-		if err := r.vms.KillVM(vm.ID); err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	})
+    return r.performVMAction(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
+        if err := r.vms.KillVM(vm.ID); err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    })
 }
 
 // Gracefully shutdown a VM based on its ID.
@@ -252,12 +252,12 @@ func (r *RouterVMs)KillVM(c echo.Context) error {
 // VM access cap: CAP_VM_STOP: any of the VMs with this cap for the logged user can be shutdown.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/shutdown -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)ShutdownVM(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
-		if err := r.vms.ShutdownVM(vm.ID); err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	})
+    return r.performVMAction(c, caps.CAP_VM_STOP_ANY, caps.CAP_VM_STOP, func(c echo.Context, vm *vms.VM) error {
+        if err := r.vms.ShutdownVM(vm.ID); err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    })
 }
 
 // Reboot a VM based on its ID.
@@ -266,12 +266,12 @@ func (r *RouterVMs)ShutdownVM(c echo.Context) error {
 // VM access cap: CAP_VM_REBOOT: any of the VMs with this cap for the logged user can be rebooted.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/stop -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)RebootVM(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(c echo.Context, vm *vms.VM) error {
-		if err := r.vms.RebootVM(vm.ID); err != nil {
-			return echo.NewHTTPError(http.StatusNotFound, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	})
+    return r.performVMAction(c, caps.CAP_VM_REBOOT_ANY, caps.CAP_VM_REBOOT, func(c echo.Context, vm *vms.VM) error {
+        if err := r.vms.RebootVM(vm.ID); err != nil {
+            return echo.NewHTTPError(http.StatusNotFound, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    })
 }
 
 // Edit a VM' specs: name, cpus, ram, nic
@@ -280,25 +280,25 @@ func (r *RouterVMs)RebootVM(c echo.Context) error {
 // VM access cap: CAP_VM_EDIT: any of the VMs with this cap for the logged user can be edited.
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59 -H 'Content-Type: application/json' -d '{"name":"Edited VM","cpus":1,"ram":2048,"nic":"user"}' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)EditVMByID(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(c echo.Context, vm *vms.VM) error {
-		// Deserializes and validates the client's parameters.
-		// Given these parameters are optional, we can't use a validator on them.
-		// Validation is performed in vm.EditVM() instead.
-		type Parameters struct {
-			Name string           `json:"name"`
-			Cpus int              `json:"cpus"`
-			Ram int               `json:"ram"`  // in MB
-			Nic vms.NicType       `json:"nic"`
-		}
-		p := new(Parameters)
-		if err := decodeJson(c, &p); err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-		}
-		if err := r.vms.EditVM(vm.ID, p.Name, p.Cpus, p.Ram, p.Nic); err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-		}
-		return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
-	})
+    return r.performVMAction(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(c echo.Context, vm *vms.VM) error {
+        // Deserializes and validates the client's parameters.
+        // Given these parameters are optional, we can't use a validator on them.
+        // Validation is performed in vm.EditVM() instead.
+        type Parameters struct {
+            Name string           `json:"name"`
+            Cpus int              `json:"cpus"`
+            Ram int               `json:"ram"`  // in MB
+            Nic vms.NicType       `json:"nic"`
+        }
+        p := new(Parameters)
+        if err := decodeJson(c, &p); err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+        }
+        if err := r.vms.EditVM(vm.ID, p.Name, p.Cpus, p.Ram, p.Nic); err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+        }
+        return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    })
 }
 
 // Set a VM access for a given user.
@@ -307,56 +307,56 @@ func (r *RouterVMs)EditVMByID(c echo.Context) error {
 // VM access cap: CAP_VM_SET_ACCESS
 // curl --cacert ca.pem -X PUT https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/caps/janedoes@nexus.org -H 'Content-Type: application/json' -d '{"caps":{"VM_LIST":1,"VM_START":1,"VM_STOP":1}}' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)SetVMAccessForUser(c echo.Context) error {
-	// Retrieves logged user from context and checks she/he has sufficient capabilities.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// Checks the user for which to set the VM Access actually exists.
-	email := c.Param("email")
-	_, err = r.users.GetUserByEmail(email)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	// Retrieves the vmID of the VM to modify.
-	vmID, err := uuid.Parse(c.Param("id"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Retrieves the VM to modify.
-	vm, err := r.vms.GetVM(vmID)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	// First, check that the logged user is the VM's owner.
-	if !vm.IsOwner(user.Email) {
-		// Next, checks the logged user has the VM_SET_ACCESS capability.
-		if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-			return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-		}
-	}
-
-	// Deserializes and validates the client's parameters.
-	type Parameters struct {
-		Access caps.Capabilities `json:"access"  validate:"required"`
-	}
-	params := new(Parameters)
-	if err := decodeJson(c, &params); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-	if err := validator.New().Struct(params); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	if err = r.vms.SetVMAccess(vmID, user.Email, email, params.Access); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-	
-	return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    // Retrieves logged user from context and checks she/he has sufficient capabilities.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // Checks the user for which to set the VM Access actually exists.
+    email := c.Param("email")
+    _, err = r.users.GetUserByEmail(email)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    // Retrieves the vmID of the VM to modify.
+    vmID, err := uuid.Parse(c.Param("id"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Retrieves the VM to modify.
+    vm, err := r.vms.GetVM(vmID)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    // First, check that the logged user is the VM's owner.
+    if !vm.IsOwner(user.Email) {
+        // Next, checks the logged user has the VM_SET_ACCESS capability.
+        if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
+            return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+        }
+    }
+
+    // Deserializes and validates the client's parameters.
+    type Parameters struct {
+        Access caps.Capabilities `json:"access"  validate:"required"`
+    }
+    params := new(Parameters)
+    if err := decodeJson(c, &params); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+    if err := validator.New().Struct(params); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    if err = r.vms.SetVMAccess(vmID, user.Email, email, params.Access); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
 }
 
 // Delete a VM Access for a given user.
@@ -365,41 +365,41 @@ func (r *RouterVMs)SetVMAccessForUser(c echo.Context) error {
 // VM access cap: CAP_VM_SET_ACCESS
 // curl --cacert ca.pem -X DELETE https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/caps/janedoes@nexus.org -H 'Content-Type: application/json' -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)DeleteVMAccessForUser(c echo.Context) error {
-	// Retrieves logged user from context and checks she/he has sufficient capabilities.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// Retrieves the vmID of the VM to modify.
-	vmID, err := uuid.Parse(c.Param("id"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-
-	// Retrieves the VM to modify.
-	vm, err := r.vms.GetVM(vmID)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	// Does not check that the user to remove the VM access for actually exists.
-	// Indeed, it might have been deleted.
-	email := c.Param("email")
-
-	// First, check that the logged user is the VM's owner.
-	if !vm.IsOwner(user.Email) {
-		// Next, checks the logged user has the VM_SET_ACCESS capability.
-		if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
-			return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-		}
-	}
-
-	if err = r.vms.DeleteVMAccess(vmID, user.Email, email); err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-	
-	return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
+    // Retrieves logged user from context and checks she/he has sufficient capabilities.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // Retrieves the vmID of the VM to modify.
+    vmID, err := uuid.Parse(c.Param("id"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    // Retrieves the VM to modify.
+    vm, err := r.vms.GetVM(vmID)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    // Does not check that the user to remove the VM access for actually exists.
+    // Indeed, it might have been deleted.
+    email := c.Param("email")
+
+    // First, check that the logged user is the VM's owner.
+    if !vm.IsOwner(user.Email) {
+        // Next, checks the logged user has the VM_SET_ACCESS capability.
+        if !user.HasCapability(caps.CAP_VM_SET_ACCESS) {
+            return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+        }
+    }
+
+    if err = r.vms.DeleteVMAccess(vmID, user.Email, email); err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+
+    return c.JSONPretty(http.StatusOK, jsonMsg("OK"), "    ")
 }
 
 // Exports a VM's directory into a compressed archive.
@@ -408,33 +408,33 @@ func (r *RouterVMs)DeleteVMAccessForUser(c echo.Context) error {
 // VM access cap: VM_READFS: any of the VMs with this cap for the logged user can have their filesystem read.
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/exportdir -H 'Content-Type: application/json' -d '{"dir":"absolute_path_to_dir"}' -H "Authorization: Bearer <AccessToken>" --output dir.tar
 func (r *RouterVMs)ExportVMDir(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(c echo.Context, vm *vms.VM) error {
-		// Deserializes and validates the client's parameter.
-		type Parameters struct {
-			Dir string  `json:"dir"`
-		}
-		p := new(Parameters)
-		if err := decodeJson(c, &p); err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-		}
-
-		// Creates a unique tar filename.
-		tmpDir := paths.GetInstance().TmpDir
-		tarGzFile := filepath.Join(tmpDir, "exportdir_"+vm.ID.String()+".tar.gz")
-
-		// Extracts VM's p.Dir directory into tarGzFile on the host.
-		if err := r.vms.ExportVMFiles(vm, p.Dir, tarGzFile); err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, "Failed extracting VM's dir")
-		}
-	
-		// Sends the archive back to the client and once completed, deletes it.
-		defer func(file string) {
-			if err := os.Remove(file); err != nil {
-				log.Error("Failed removing archive of extracted VM dir: "+err.Error())
-			}
-		}(tarGzFile)
-		return c.File(tarGzFile)
-	})
+    return r.performVMAction(c, caps.CAP_VM_READFS_ANY, caps.CAP_VM_READFS, func(c echo.Context, vm *vms.VM) error {
+        // Deserializes and validates the client's parameter.
+        type Parameters struct {
+            Dir string  `json:"dir"`
+        }
+        p := new(Parameters)
+        if err := decodeJson(c, &p); err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+        }
+
+        // Creates a unique tar filename.
+        tmpDir := paths.GetInstance().TmpDir
+        tarGzFile := filepath.Join(tmpDir, "exportdir_"+vm.ID.String()+".tar.gz")
+
+        // Extracts VM's p.Dir directory into tarGzFile on the host.
+        if err := r.vms.ExportVMFiles(vm, p.Dir, tarGzFile); err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, "Failed extracting VM's dir")
+        }
+
+        // Sends the archive back to the client and once completed, deletes it.
+        defer func(file string) {
+            if err := os.Remove(file); err != nil {
+                log.Error("Failed removing archive of extracted VM dir: "+err.Error())
+            }
+        }(tarGzFile)
+        return c.File(tarGzFile)
+    })
 }
 
 // Import files into a VM's filesystem, in a specified directory. The file tree is received in a tar.gz archive.
@@ -443,48 +443,48 @@ func (r *RouterVMs)ExportVMDir(c echo.Context) error {
 // VM access cap: VM_WRITEFS: any of the VMs with this cap for the logged user can import the file tree.
 // curl --cacert ca.pem -X POST https://localhost:1077/vms/e41f3556-ca24-4658-bd79-8c85bd6bff59/importfiles -H 'Content-Type: multipart/form-data' -F dir="/home/nexus" -F file=@files.tar -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
-	return r.performVMAction(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(c echo.Context, vm *vms.VM) error {
-		// Retrieves the various client arguments.
-		vmDir := c.FormValue("vmDir")
-
-		// Retrieves the tar.gz archive (uploadedtarGzFile).
-		tarGzFile, err := c.FormFile("file")
-		if err != nil {
-			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-		}
-
-		src, err := tarGzFile.Open()
-		if err != nil {
-			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-		}
-		defer src.Close()
-	
-		tmpDir := paths.GetInstance().TmpDir
-		uuid, err := uuid.NewRandom()
-		if err != nil {
-			log.Error("Failed creating random UUID: "+err.Error())
-			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-		}
-		uploadedtarGzFile := filepath.Join(tmpDir, "upload_"+uuid.String()+".tar")
-		dst, err := os.Create(uploadedtarGzFile)
-		if err != nil {
-			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-		}
-		defer dst.Close()
-		defer os.Remove(uploadedtarGzFile)
-	
-		if _, err = io.Copy(dst, src); err != nil {
-			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
-		}
-
-		// Copy the archive's files into the VM
-		// IMPORTANT: check the VM is NOT running!
-		if err = r.vms.ImportFilesToVM(vm, uploadedtarGzFile, vmDir); err != nil {
-			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-		}
-	
-		return c.JSONPretty(http.StatusCreated, jsonMsg("OK"), "    ")
-	})
+    return r.performVMAction(c, caps.CAP_VM_WRITEFS_ANY, caps.CAP_VM_WRITEFS, func(c echo.Context, vm *vms.VM) error {
+        // Retrieves the various client arguments.
+        vmDir := c.FormValue("vmDir")
+
+        // Retrieves the tar.gz archive (uploadedtarGzFile).
+        tarGzFile, err := c.FormFile("file")
+        if err != nil {
+            return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+        }
+
+        src, err := tarGzFile.Open()
+        if err != nil {
+            return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+        }
+        defer src.Close()
+
+        tmpDir := paths.GetInstance().TmpDir
+        uuid, err := uuid.NewRandom()
+        if err != nil {
+            log.Error("Failed creating random UUID: "+err.Error())
+            return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+        }
+        uploadedtarGzFile := filepath.Join(tmpDir, "upload_"+uuid.String()+".tar")
+        dst, err := os.Create(uploadedtarGzFile)
+        if err != nil {
+            return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+        }
+        defer dst.Close()
+        defer os.Remove(uploadedtarGzFile)
+
+        if _, err = io.Copy(dst, src); err != nil {
+            return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+        }
+
+        // Copy the archive's files into the VM
+        // IMPORTANT: check the VM is NOT running!
+        if err = r.vms.ImportFilesToVM(vm, uploadedtarGzFile, vmDir); err != nil {
+            return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+        }
+
+        return c.JSONPretty(http.StatusCreated, jsonMsg("OK"), "    ")
+    })
 }
 
 // Helper function that returns a list of serialized VMs that match either:
@@ -493,35 +493,35 @@ func (r *RouterVMs)ImportFilesToVM(c echo.Context) error {
 // - the VM access for the logged user matches the vmAccessCapability capability.
 // Also, VMs for which cond is false are filtered out.
 func (r *RouterVMs)performVMsList(c echo.Context, userCapabilityAny, vmAccessCapability string, cond vms.VMKeeperFn) error {
-	// Retrieves logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// If the logged user has the XX_ANY capability (userCapabilityAny), returns all VMs.
-	if user.HasCapability(userCapabilityAny) {
-		// Returns all VMs that pass the condition.
-		return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(cond), "    ")
-	} else {
-		// Returns all VMs:
-		// - owned by the logged user
-		// - for which the logged user has the specified capability (vmAccessCapability) in the VM's access
-		return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(
-			func(vm vms.VM) bool {
-				if vm.IsOwner(user.Email) {
-					return true
-				} else {
-					capabilities, exists := vm.Access[user.Email]
-					if exists {
-						_, visible := capabilities[vmAccessCapability]
-						return visible && cond(vm)
-					} else {
-						return false
-					}
-				}
-			  }), "    ")
-	}
+    // Retrieves logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // If the logged user has the XX_ANY capability (userCapabilityAny), returns all VMs.
+    if user.HasCapability(userCapabilityAny) {
+        // Returns all VMs that pass the condition.
+        return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(cond), "    ")
+    } else {
+        // Returns all VMs:
+        // - owned by the logged user
+        // - for which the logged user has the specified capability (vmAccessCapability) in the VM's access
+        return c.JSONPretty(http.StatusOK, r.vms.GetNetworkSerializedVMs(
+            func(vm vms.VM) bool {
+                if vm.IsOwner(user.Email) {
+                    return true
+                } else {
+                    capabilities, exists := vm.Access[user.Email]
+                    if exists {
+                        _, visible := capabilities[vmAccessCapability]
+                        return visible && cond(vm)
+                    } else {
+                        return false
+                    }
+                }
+              }), "    ")
+    }
 }
 
 // Helper function that performs an action on a VM based either on:
@@ -529,40 +529,40 @@ func (r *RouterVMs)performVMsList(c echo.Context, userCapabilityAny, vmAccessCap
 // - the logged user has the userCapabilityAny capability.
 // - the VM access for the logged user matches the vmAccessCapability capability.
 func (r *RouterVMs)performVMAction(c echo.Context, userCapabilityAny, vmAccessCapability string, action vmActionFn) error {
-	// Retrieves the VM on which to perform the action.
-	id, err := uuid.Parse(c.Param("id"))
-	if err != nil {
-		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
-	}
-	vm, err := r.vms.GetVM(id)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusNotFound, err.Error())
-	}
-
-	// Retrieves the logged user from context.
-	user, err := getLoggedUser(r.users, c)
-	if err != nil {
-		return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
-	}
-
-	// First, checks if the user is the VM's owner
-	if vm.IsOwner(user.Email) {
-		return action(c, &vm)
-	} else if user.HasCapability(userCapabilityAny) {
-		// Next, checks if the user has the XX_ANY capability
-		return action(c, &vm)
-	} else {
-		// Finally, check if the VM access for the logged user matches the required capability
-		userCaps, exists := vm.Access[user.Email]
-		if !exists {
-			return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-		}
-
-		_, hasAccess := userCaps[vmAccessCapability]
-		if !hasAccess {
-			return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
-		}
-
-		return action(c, &vm)
-	}
+    // Retrieves the VM on which to perform the action.
+    id, err := uuid.Parse(c.Param("id"))
+    if err != nil {
+        return echo.NewHTTPError(http.StatusBadRequest, err.Error())
+    }
+    vm, err := r.vms.GetVM(id)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusNotFound, err.Error())
+    }
+
+    // Retrieves the logged user from context.
+    user, err := getLoggedUser(r.users, c)
+    if err != nil {
+        return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
+    }
+
+    // First, checks if the user is the VM's owner
+    if vm.IsOwner(user.Email) {
+        return action(c, &vm)
+    } else if user.HasCapability(userCapabilityAny) {
+        // Next, checks if the user has the XX_ANY capability
+        return action(c, &vm)
+    } else {
+        // Finally, check if the VM access for the logged user matches the required capability
+        userCaps, exists := vm.Access[user.Email]
+        if !exists {
+            return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+        }
+
+        _, hasAccess := userCaps[vmAccessCapability]
+        if !hasAccess {
+            return echo.NewHTTPError(http.StatusUnauthorized, msgInsufficientCaps)
+        }
+
+        return action(c, &vm)
+    }
 }
diff --git a/src/router/routerVersion.go b/src/router/routerVersion.go
index bfad7e390ce8151102a26ef2ed12363f95b68f40..60e9644191b7d6d1a8bcba3b34ff90d90972b735 100644
--- a/src/router/routerVersion.go
+++ b/src/router/routerVersion.go
@@ -1,8 +1,8 @@
 package router
 
 import (
-	"net/http"
-	"nexus-server/version"
+    "net/http"
+    "nexus-server/version"
     "github.com/labstack/echo/v4"
 )
 
@@ -10,11 +10,11 @@ type RouterVersion struct {
 }
 
 func NewRouterVersion() *RouterVersion {
-	return &RouterVersion{}
+    return &RouterVersion{}
 }
 
 // Retrives the version number.
 // curl --cacert ca.pem -X GET http://localhost:1077/version
 func (r *RouterVersion)GetVersion(c echo.Context) error {
-	return c.JSON(http.StatusOK, echo.Map{"version": version.Get().String()})
+    return c.JSON(http.StatusOK, echo.Map{"version": version.Get().String()})
 }
diff --git a/src/users/user.go b/src/users/user.go
index a53511d38619884a370e54de87147febf3c1ca69..9f4b2ce85961e00eb4ab9c4026ba50fb85454425 100644
--- a/src/users/user.go
+++ b/src/users/user.go
@@ -1,56 +1,56 @@
 package users
 
 import (
-	"nexus-server/caps"
-	"github.com/go-playground/validator/v10"
+    "nexus-server/caps"
+    "github.com/go-playground/validator/v10"
 )
 
 type User struct {
-	Email     string            `json:"email"     validate:"required,email"`
-	FirstName string            `json:"firstname" validate:"required,min=2,max=32"`
-	LastName  string            `json:"lastname"  validate:"required,min=2,max=32"`
-	Pwd       string            `json:"pwd"       validate:"required,min=8"`
-	Caps      caps.Capabilities `json:"caps"      validate:"required"`
+    Email     string            `json:"email"     validate:"required,email"`
+    FirstName string            `json:"firstname" validate:"required,min=2,max=32"`
+    LastName  string            `json:"lastname"  validate:"required,min=2,max=32"`
+    Pwd       string            `json:"pwd"       validate:"required,min=8"`
+    Caps      caps.Capabilities `json:"caps"      validate:"required"`
 }
 
 type UserWithoutPwd struct {
-	Email     string            `json:"email"     validate:"required,email"`
-	FirstName string            `json:"firstname" validate:"required,min=2,max=32"`
-	LastName  string            `json:"lastname"  validate:"required,min=2,max=32"`
-	Caps      caps.Capabilities `json:"caps"      validate:"required"`
+    Email     string            `json:"email"     validate:"required,email"`
+    FirstName string            `json:"firstname" validate:"required,min=2,max=32"`
+    LastName  string            `json:"lastname"  validate:"required,min=2,max=32"`
+    Caps      caps.Capabilities `json:"caps"      validate:"required"`
 }
 
 var dummyUser = User{}
 
 // Creates an empty user.
 func NewEmptyUser() *User {
-	return &User{Email: "", FirstName: "", LastName: "", Caps: make(caps.Capabilities), Pwd: ""}
+    return &User{Email: "", FirstName: "", LastName: "", Caps: make(caps.Capabilities), Pwd: ""}
 }
 
 // Checks that the User structure's fields are valid.
 func (user *User) Validate() error {
-	// Checks the capabilities are valid
-	if err := caps.ValidateUserCaps(user.Caps); err != nil {
-		return err
-	}
+    // Checks the capabilities are valid
+    if err := caps.ValidateUserCaps(user.Caps); err != nil {
+        return err
+    }
 
-	validate := validator.New()
-	return validate.Struct(user)
+    validate := validator.New()
+    return validate.Struct(user)
 }
 
 // Returns true if user has the specified capability.
 func (user *User) HasCapability(capability string) bool {
-	_, exists := user.Caps[capability]
-	return exists
+    _, exists := user.Caps[capability]
+    return exists
 }
 
 func (user *User) GetVMAccessCapabilities() []string {
-	capabilities := []string{}
-	for cap, _ := range caps.VMAccessCaps {
-		_, exists := user.Caps[cap]
-		if exists {
-			capabilities = append(capabilities, cap)
-		}
-	}
-	return capabilities
+    capabilities := []string{}
+    for cap, _ := range caps.VMAccessCaps {
+        _, exists := user.Caps[cap]
+        if exists {
+            capabilities = append(capabilities, cap)
+        }
+    }
+    return capabilities
 }
diff --git a/src/users/users.go b/src/users/users.go
index 6f431c427677942a73166ff8a4ecfd1b3cc4ac5a..396866e22a2e0e30ae520119af71038d96a24a22 100644
--- a/src/users/users.go
+++ b/src/users/users.go
@@ -1,19 +1,19 @@
 package users
 
 import (
-	"os"
-	"sort"
-	"sync"
-	"errors"
-	"encoding/json"
-	"nexus-server/paths"
-	"nexus-server/logger"
+    "os"
+    "sort"
+    "sync"
+    "errors"
+    "encoding/json"
+    "nexus-server/paths"
+    "nexus-server/logger"
 )
 
 type Users struct {
-	m map[string]User
-	file string
-	rwlock *sync.RWMutex
+    m map[string]User
+    file string
+    rwlock *sync.RWMutex
 }
 
 var log = logger.GetInstance()
@@ -22,152 +22,152 @@ var users *Users
 // Returns a Users "singleton".
 // IMPORTANT: the InitUsers function must have been previously called!
 func GetUsersInstance() *Users {
-	return users
+    return users
 }
 
 // Creates users by reading them from the config directory.
 func InitUsers() error {
-	usersFile := paths.GetInstance().UsersFile
-	users = &Users { m: make(map[string]User), file: usersFile, rwlock: new(sync.RWMutex) }
-	return users.createUsersFromFile()
+    usersFile := paths.GetInstance().UsersFile
+    users = &Users { m: make(map[string]User), file: usersFile, rwlock: new(sync.RWMutex) }
+    return users.createUsersFromFile()
 }
 
 // Returns all users.
 // Thread-safe fonction.
 func (users *Users)GetUsers() []User {
-	users.rwlock.RLock()
-	list := users.usersToList()
-	users.rwlock.RUnlock()
-	
-	// Sort users by names
-	sort.Slice(list, func(i, j int) bool {
+    users.rwlock.RLock()
+    list := users.usersToList()
+    users.rwlock.RUnlock()
+
+    // Sort users by names
+    sort.Slice(list, func(i, j int) bool {
         return list[i].LastName < list[j].LastName
     })
-	return list
+    return list
 }
 
 // Returns a user by her email (unique).
 // Thread-safe fonction.
 func (users *Users)GetUserByEmail(email string) (User, error) {
-	users.rwlock.RLock()
-	defer users.rwlock.RUnlock()
+    users.rwlock.RLock()
+    defer users.rwlock.RUnlock()
 
-	for _, u := range users.m {
-		if email == u.Email {
-			return u, nil
-		}
-	}
+    for _, u := range users.m {
+        if email == u.Email {
+            return u, nil
+        }
+    }
 
-	return dummyUser, errors.New(email+": user not found")
+    return dummyUser, errors.New(email+": user not found")
 }
 
 // Deletes a user by its email and upates the user file.
 // TODO: only deletes a user when no VMs and templates are owned by her?
 // Thread-safe fonction.
 func (users *Users)DeleteUserByEmail(email string) error {
-	users.rwlock.Lock()
-	defer users.rwlock.Unlock()
-	key := email
-	_, exists := users.m[key]
-	if exists {
-		delete(users.m, key)
-		err := users.writeUsersFile()
-		return err
-	}
-	return errors.New(email+": user not found")
+    users.rwlock.Lock()
+    defer users.rwlock.Unlock()
+    key := email
+    _, exists := users.m[key]
+    if exists {
+        delete(users.m, key)
+        err := users.writeUsersFile()
+        return err
+    }
+    return errors.New(email+": user not found")
 }
 
 // Adds a user and updates the users file.
 // Thread-safe fonction.
 func (users *Users)AddUser(user *User) error {
-	users.rwlock.Lock()
-	defer users.rwlock.Unlock()
-
-	// Checks the username doesn't already exists.
-	for _, u := range users.m {
-		if user.Email == u.Email {
-			return errors.New("User already exists")
-		}
-	}
-
-	key := user.Email
-	users.m[key] = *user
-	err := users.writeUsersFile()
-	return err
+    users.rwlock.Lock()
+    defer users.rwlock.Unlock()
+
+    // Checks the username doesn't already exists.
+    for _, u := range users.m {
+        if user.Email == u.Email {
+            return errors.New("User already exists")
+        }
+    }
+
+    key := user.Email
+    users.m[key] = *user
+    err := users.writeUsersFile()
+    return err
 }
 
 // Updates a user and updates the user file.
 // Thread-safe fonction.
 func (users *Users)UpdateUser(user *User) error {
-	users.rwlock.Lock()
-	defer users.rwlock.Unlock()
-	key := user.Email
-	_, exists := users.m[key]
-	if exists {
-		// Deletes previous user and adds new one
-		delete(users.m, key)
-		users.m[key] = *user
-		err := users.writeUsersFile()
-		return err
-	}
-	return errors.New(key+": user not found")
+    users.rwlock.Lock()
+    defer users.rwlock.Unlock()
+    key := user.Email
+    _, exists := users.m[key]
+    if exists {
+        // Deletes previous user and adds new one
+        delete(users.m, key)
+        users.m[key] = *user
+        err := users.writeUsersFile()
+        return err
+    }
+    return errors.New(key+": user not found")
 }
 
 // Creates users by reading them from the user file.
 func (users *Users)createUsersFromFile() error {
-	filein, err := os.OpenFile(users.file, os.O_RDONLY, 0)
-	if err != nil {
+    filein, err := os.OpenFile(users.file, os.O_RDONLY, 0)
+    if err != nil {
         return errors.New("Failed reading users file: "+err.Error())
-	}
-	defer filein.Close()
-
-	// Decodes the json file into users, then checks:
-	// - all fields are present
-	// - extra fields are not allowed
-	decoder := json.NewDecoder(filein)
-	decoder.DisallowUnknownFields()
-	usersAsList := []User{}
-	if err = decoder.Decode(&usersAsList); err != nil {
-		return errors.New("Failed decoding users file \""+users.file+"\": "+err.Error())
-	}
-
-	// Validates each user entry
-	for _, u := range usersAsList {
-		if err = u.Validate(); err != nil {
-			return errors.New("Failed validating users file \""+users.file+"\": "+err.Error())
-		}
-		// Add the entry to the map of users
-		key := u.Email
-		users.m[key] = u
-	}
-	
-	return nil
+    }
+    defer filein.Close()
+
+    // Decodes the json file into users, then checks:
+    // - all fields are present
+    // - extra fields are not allowed
+    decoder := json.NewDecoder(filein)
+    decoder.DisallowUnknownFields()
+    usersAsList := []User{}
+    if err = decoder.Decode(&usersAsList); err != nil {
+        return errors.New("Failed decoding users file \""+users.file+"\": "+err.Error())
+    }
+
+    // Validates each user entry
+    for _, u := range usersAsList {
+        if err = u.Validate(); err != nil {
+            return errors.New("Failed validating users file \""+users.file+"\": "+err.Error())
+        }
+        // Add the entry to the map of users
+        key := u.Email
+        users.m[key] = u
+    }
+
+    return nil
 }
 
 // Writes users to file.
 func (users *Users)writeUsersFile() error {
-	file, err := os.Create(users.file)
-	if err != nil {
-		log.Error("Failed writing users file: "+err.Error())
+    file, err := os.Create(users.file)
+    if err != nil {
+        log.Error("Failed writing users file: "+err.Error())
         return errors.New("Failed writing users file: "+err.Error())
-	}
-	defer file.Close()
-
-	encoder := json.NewEncoder(file)
-	encoder.SetIndent("", "    ")
-	usersAsList := users.usersToList()
-	if err = encoder.Encode(&usersAsList); err != nil {
-		log.Error("Failed encoding users file \""+users.file+"\": "+err.Error())
-		return errors.New("Failed encoding users file \""+users.file+"\": "+err.Error())
-	}
-	return nil
+    }
+    defer file.Close()
+
+    encoder := json.NewEncoder(file)
+    encoder.SetIndent("", "    ")
+    usersAsList := users.usersToList()
+    if err = encoder.Encode(&usersAsList); err != nil {
+        log.Error("Failed encoding users file \""+users.file+"\": "+err.Error())
+        return errors.New("Failed encoding users file \""+users.file+"\": "+err.Error())
+    }
+    return nil
 }
 
 // Converts the map of users into a list.
 func (users *Users)usersToList() []User {
-	list := []User{}
-	for _, val := range users.m {
-		list = append(list, val)
-	}
-	return list
+    list := []User{}
+    for _, val := range users.m {
+        list = append(list, val)
+    }
+    return list
 }
diff --git a/src/utils/memory.go b/src/utils/memory.go
index 70b8c0e4d255f51e29dba54ba7013fad8d5dec46..7ad76396b551a77d3aeff4d0e6528f730902a6ec 100644
--- a/src/utils/memory.go
+++ b/src/utils/memory.go
@@ -1,10 +1,10 @@
 package utils
 
 import (
-	"os"
-	"bufio"
-	"strconv"
-	"strings"
+    "os"
+    "bufio"
+    "strconv"
+    "strings"
 )
 
 // This function returns info about the system's RAM
@@ -12,37 +12,37 @@ import (
 // Beware: it is Linux SPECIFIC!
 // Returns total and avaiable memory in MB.
 func GetRAM() (int, int, error) {
-	f, err := os.Open("/proc/meminfo")
+    f, err := os.Open("/proc/meminfo")
     if err != nil {
-		return 0, 0, err
+        return 0, 0, err
     }
-	defer f.Close()
+    defer f.Close()
 
     scan := bufio.NewScanner(f)
     scan.Split(bufio.ScanLines)
 
-	var memTotal int = -1
-	var memAvail int = -1
-	const units = 1024
+    var memTotal int = -1
+    var memAvail int = -1
+    const units = 1024
 
     for scan.Scan() {
-		s := scan.Text()
-		fields := strings.Split(s, ":")
-		attr := fields[0]
-		vals := strings.Split(strings.TrimSpace(fields[1]), " ")
-		val := strings.TrimSpace(vals[0])
-		attr = strings.TrimSpace(strings.ToLower(attr))
-		switch attr {
-		case "memtotal":
-			memTotal, _ = strconv.Atoi(val)
-			memTotal = memTotal/units
-		case "memavailable":
-			memAvail, _ = strconv.Atoi(val)
-			memAvail = memAvail/units
-		}
+        s := scan.Text()
+        fields := strings.Split(s, ":")
+        attr := fields[0]
+        vals := strings.Split(strings.TrimSpace(fields[1]), " ")
+        val := strings.TrimSpace(vals[0])
+        attr = strings.TrimSpace(strings.ToLower(attr))
+        switch attr {
+        case "memtotal":
+            memTotal, _ = strconv.Atoi(val)
+            memTotal = memTotal/units
+        case "memavailable":
+            memAvail, _ = strconv.Atoi(val)
+            memAvail = memAvail/units
+        }
     }
 
-	return memTotal, memAvail, nil
+    return memTotal, memAvail, nil
 }
 
 /*
@@ -50,18 +50,18 @@ func GetRAM() (int, int, error) {
 // Returns: total RAM, shared RAM, buffered RAM, free RAM and possibly an error.
 // RAM amounts are given in megabytes (MB).
 func GetRAM() (int, int, int, int, error) {
-	in := &syscall.Sysinfo_t{}
-	if err := syscall.Sysinfo(in); err != nil {
-		return 0, 0, 0, 0, err
-	}
+    in := &syscall.Sysinfo_t{}
+    if err := syscall.Sysinfo(in); err != nil {
+        return 0, 0, 0, 0, err
+    }
 
-	const MB = 1024*1024
-	// On 32-bit systems these fields are uint32 instead of uint64.
-	// We always convert to uint64 to match signature.
-	totalRam :=  int(uint64(in.Totalram)*uint64(in.Unit)/MB)
-	sharedRam :=  int(uint64(in.Sharedram)*uint64(in.Unit)/MB)
-	bufferedRam := int(uint64(in.Bufferram)*uint64(in.Unit)/MB)
-	freeRam := int(uint64(in.Freeram)*uint64(in.Unit)/MB)
-	return totalRam, sharedRam, bufferedRam, freeRam, nil
+    const MB = 1024*1024
+    // On 32-bit systems these fields are uint32 instead of uint64.
+    // We always convert to uint64 to match signature.
+    totalRam :=  int(uint64(in.Totalram)*uint64(in.Unit)/MB)
+    sharedRam :=  int(uint64(in.Sharedram)*uint64(in.Unit)/MB)
+    bufferedRam := int(uint64(in.Bufferram)*uint64(in.Unit)/MB)
+    freeRam := int(uint64(in.Freeram)*uint64(in.Unit)/MB)
+    return totalRam, sharedRam, bufferedRam, freeRam, nil
 }
 */
\ No newline at end of file
diff --git a/src/utils/utils.go b/src/utils/utils.go
index 32bf340e8e10b622dc58f9c070d74b4b76214663..45cdd1eaa7e377b60c89568db1b11e7311504868 100644
--- a/src/utils/utils.go
+++ b/src/utils/utils.go
@@ -1,177 +1,177 @@
 package utils
 
 import (
-	"os"
-	"io"
-	"net"
-	"time"
-	"strings"
-	"strconv"
-	"math/rand"
-	"archive/tar"
-	"path/filepath"
-	"nexus-server/logger"
-	"golang.org/x/crypto/bcrypt"
+    "os"
+    "io"
+    "net"
+    "time"
+    "strings"
+    "strconv"
+    "math/rand"
+    "archive/tar"
+    "path/filepath"
+    "nexus-server/logger"
+    "golang.org/x/crypto/bcrypt"
 )
 
 var log = logger.GetInstance()
 
 // Returns the list of subdirectories present in dir.
 func GetSubDirs(dir string) ([]string, error) {
-	subDirs := []string{}
-
-	currentDir, err := os.Open(dir)
-	if err != nil {
-		return nil, err
-	}
-
-	// Retrieves all files entries in the directory (0 = all files in the directory).
-	files, err := currentDir.Readdir(0)
-	if err != nil {
-		currentDir.Close()
-		return nil, err
-	}
-
-	currentDir.Close()
-
-	// Loop over file entries
-	for _, f := range(files) {
-		if f.IsDir() {
-			subDirs = append(subDirs, filepath.Join(dir, f.Name()))
-		}
-	}
-
-	return subDirs, nil
+    subDirs := []string{}
+
+    currentDir, err := os.Open(dir)
+    if err != nil {
+        return nil, err
+    }
+
+    // Retrieves all files entries in the directory (0 = all files in the directory).
+    files, err := currentDir.Readdir(0)
+    if err != nil {
+        currentDir.Close()
+        return nil, err
+    }
+
+    currentDir.Close()
+
+    // Loop over file entries
+    for _, f := range(files) {
+        if f.IsDir() {
+            subDirs = append(subDirs, filepath.Join(dir, f.Name()))
+        }
+    }
+
+    return subDirs, nil
 }
 
 // Initializes the random number generator.
 func RandInit() {
-	rand.Seed(time.Now().UnixNano())
+    rand.Seed(time.Now().UnixNano())
 }
 
 // Returns an int in the range [min,max] (both inclusive).
 func Rand(min, max int) int {
-	return rand.Intn(max-min+1)+min
+    return rand.Intn(max-min+1)+min
 }
 
 func CopyFiles(source, dest string) error {
-	src, err := os.Open(source)
-	if err != nil {
-		return err
-	}
-	defer src.Close()
-
-	dst, err := os.Create(dest)
-	if err != nil {
-		return err
-	}
-	defer dst.Close()
-	_, err = io.Copy(dst, src)
-
-	return err
+    src, err := os.Open(source)
+    if err != nil {
+        return err
+    }
+    defer src.Close()
+
+    dst, err := os.Create(dest)
+    if err != nil {
+        return err
+    }
+    defer dst.Close()
+    _, err = io.Copy(dst, src)
+
+    return err
 }
 
 // Returns a hash of the "clear" password passed in argument.
 func HashPassword(pwd string) string {
-	// Uses bcrypt to hash the password.
-	hashedPwd, _ := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
-	return string(hashedPwd)
+    // Uses bcrypt to hash the password.
+    hashedPwd, _ := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
+    return string(hashedPwd)
 }
 
 // Returns a random MAC address as a string (e.g. "b3:30:49:f8:d0:4b").
 func RandMacAddress() (string, error) {
-	buf := make([]byte, 6)
-	_, err  := rand.Read(buf)
-	if err != nil {
-		return "", err
-	}
-	
-	// Sets unicast mode (bit 0 to 0) and locally administered addresses (bit 1 to 1)
-	// For more details, see: https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local_(U/L_bit)
-	buf[0] &= 0xFE
-	buf[0] |= 2
-
-	var mac net.HardwareAddr
-	mac = append(mac, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5])
-	return mac.String(), nil
+    buf := make([]byte, 6)
+    _, err  := rand.Read(buf)
+    if err != nil {
+        return "", err
+    }
+
+    // Sets unicast mode (bit 0 to 0) and locally administered addresses (bit 1 to 1)
+    // For more details, see: https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local_(U/L_bit)
+    buf[0] &= 0xFE
+    buf[0] |= 2
+
+    var mac net.HardwareAddr
+    mac = append(mac, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5])
+    return mac.String(), nil
 }
 
 // Returns true if the specified file exists, false otherwise.
 func FileExists(filename string) bool {
-	info, err := os.Stat(filename)
-	if os.IsNotExist(err) {
-	   return false
-	}
-	return !info.IsDir()
+    info, err := os.Stat(filename)
+    if os.IsNotExist(err) {
+       return false
+    }
+    return !info.IsDir()
 }
 
 // Returns true if the specified TCP port is available, false otherwise.
 func IsPortAvailable(port int) bool {
-	ln, err := net.Listen("tcp", ":" + strconv.Itoa(port))
-	if err != nil {
-		return false
-	}
-	ln.Close()
-	return true
+    ln, err := net.Listen("tcp", ":" + strconv.Itoa(port))
+    if err != nil {
+        return false
+    }
+    ln.Close()
+    return true
 }
 
 // Creates the destTarball .tar archive of srcDir and all its files and subdirectories.
 // This implementation fails if a symlink points to an absolute path that doesn't exist on the host.
 // Source code slightly modified from: https://golangdocs.com/tar-gzip-in-golang
 func TarDir(srcDir, destTarball string) error {
-	tarFile, err := os.Create(destTarball)
+    tarFile, err := os.Create(destTarball)
     if err != nil {
         return err
     }
     defer tarFile.Close()
- 
+
     tarball := tar.NewWriter(tarFile)
     defer tarball.Close()
- 
+
     info, err := os.Stat(srcDir)
     if err != nil {
         return err
     }
- 
+
     var baseDir string
     if info.IsDir() {
         baseDir = filepath.Base(srcDir)
     }
- 
+
     return filepath.Walk(srcDir,
         func(path string, info os.FileInfo, err error) error {
             if err != nil {
                 return err
-			}
-			
-			if (info.Mode() & os.ModeSymlink) != 0 {
-				log.Warn("TarDir: skipping symlink: ", path)
-				return nil
-			}
-
-			header, err := tar.FileInfoHeader(info, info.Name())
+            }
+
+            if (info.Mode() & os.ModeSymlink) != 0 {
+                log.Warn("TarDir: skipping symlink: ", path)
+                return nil
+            }
+
+            header, err := tar.FileInfoHeader(info, info.Name())
             if err != nil {
                 return err
-			}
- 
+            }
+
             if baseDir != "" {
                 header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, srcDir))
             }
- 
+
             if err := tarball.WriteHeader(header); err != nil {
                 return err
             }
- 
+
             if info.IsDir() {
                 return nil
             }
- 
+
             file, err := os.Open(path)
             if err != nil {
                 return err
             }
             defer file.Close()
-			_, err = io.Copy(tarball, file)
+            _, err = io.Copy(tarball, file)
             return err
         })
 }
@@ -182,9 +182,9 @@ func Untar(srcTarball, destDir string) error {
     if err != nil {
         return err
     }
-	defer reader.Close()
-	
-	// First pass: reads and creates directories first.
+    defer reader.Close()
+
+    // First pass: reads and creates directories first.
     tarDirReader := tar.NewReader(reader)
     for {
         header, err := tarDirReader.Next()
@@ -192,7 +192,7 @@ func Untar(srcTarball, destDir string) error {
             break
         } else if err != nil {
             return err
-		}
+        }
         path := filepath.Join(destDir, header.Name)
         info := header.FileInfo()
         if info.IsDir() {
@@ -201,34 +201,34 @@ func Untar(srcTarball, destDir string) error {
             }
             continue
         }
-	}
-
-	// Seeks to the beginning of the file.
-	whence := 0
-	reader.Seek(0, whence)
-	
-	// Second pass: reads and creates files.
-	tarFileReader := tar.NewReader(reader)
+    }
+
+    // Seeks to the beginning of the file.
+    whence := 0
+    reader.Seek(0, whence)
+
+    // Second pass: reads and creates files.
+    tarFileReader := tar.NewReader(reader)
     for {
         header, err := tarFileReader.Next()
         if err == io.EOF {
             break
         } else if err != nil {
             return err
-		}
+        }
         path := filepath.Join(destDir, header.Name)
-		info := header.FileInfo()
-		if !info.IsDir() {
-			file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
-			if err != nil {
-				return err
-			}
-			defer file.Close()
-			_, err = io.Copy(file, tarFileReader)
-			if err != nil {
-				return err
-			}
-		}
+        info := header.FileInfo()
+        if !info.IsDir() {
+            file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
+            if err != nil {
+                return err
+            }
+            defer file.Close()
+            _, err = io.Copy(file, tarFileReader)
+            if err != nil {
+                return err
+            }
+        }
     }
 
     return nil
diff --git a/src/version/version.go b/src/version/version.go
index 804b0773863e7d8dc074c99231acaa433a71bffd..45abd3ec7d26b8f1c8299766d0dad2dc7bbaf0ae 100644
--- a/src/version/version.go
+++ b/src/version/version.go
@@ -1,31 +1,31 @@
 package version
 
 import (
-	"strconv"
+    "strconv"
 )
 
 const (
-	major  = 1
-	minor  = 5
-	bugfix = 0
+    major  = 1
+    minor  = 5
+    bugfix = 0
 )
 
 type Version struct {
-	major int
-	minor int
-	bugfix int
+    major int
+    minor int
+    bugfix int
 }
 
 var version Version = FromInt(major, minor, bugfix)
 
 func FromInt(major, minor, bugfix int) Version {
-	return Version{major, minor, bugfix}
+    return Version{major, minor, bugfix}
 }
 
 func Get() Version {
-	return version
+    return version
 }
 
 func (v Version) String() string {
-	return strconv.Itoa(v.major)+"."+strconv.Itoa(v.minor)+"."+strconv.Itoa(v.bugfix)
+    return strconv.Itoa(v.major)+"."+strconv.Itoa(v.minor)+"."+strconv.Itoa(v.bugfix)
 }
diff --git a/src/vms/template.go b/src/vms/template.go
index 52b4584d632551c2975f030abe717d03a42681e7..6a445b0ceeb59621c06a3af8670d1c482d69541a 100644
--- a/src/vms/template.go
+++ b/src/vms/template.go
@@ -1,218 +1,218 @@
 package vms
 
 import (
-	"os"
-	"time"
-	"errors"
-	"path/filepath"
-	"encoding/json"
-	"nexus-server/exec"
-	"nexus-server/utils"
-	"github.com/google/uuid"
-	"github.com/go-playground/validator/v10"
+    "os"
+    "time"
+    "errors"
+    "path/filepath"
+    "encoding/json"
+    "nexus-server/exec"
+    "nexus-server/utils"
+    "github.com/google/uuid"
+    "github.com/go-playground/validator/v10"
 )
 
 type Template struct {
-	ID uuid.UUID           `json:"id"           validate:"required"`
-	Name string            `json:"name"         validate:"required,min=2,max=256"`
-	Owner string           `json:"owner"        validate:"required,email"`
-	Access string          `json:"access"       validate:"required,min=4,max=16"` // private or public
-	CreationTime time.Time `json:"creationTime" validate:"required"`
+    ID uuid.UUID           `json:"id"           validate:"required"`
+    Name string            `json:"name"         validate:"required,min=2,max=256"`
+    Owner string           `json:"owner"        validate:"required,email"`
+    Access string          `json:"access"       validate:"required,min=4,max=16"` // private or public
+    CreationTime time.Time `json:"creationTime" validate:"required"`
 }
 
 const (
-	templateConfFile = "template.json"
-	templateDiskFile = "disk.qcow"
+    templateConfFile = "template.json"
+    templateDiskFile = "disk.qcow"
 
-	templatePublic  = "public"
-	templatePrivate = "private"
+    templatePublic  = "public"
+    templatePrivate = "private"
 )
 
 var dummyTemplate = Template{}
 
 // Creates a template from a VM's disk.
 func NewTemplateFromVM(name, owner, access string, vm *VM) (*Template, error) {
-	// Marks the VM to copy from as being busy.
-	if err := vms.setDiskBusy(vm); err != nil {
-		return nil, errors.New("Failed setting disk busy flag during template creation: " + err.Error())
-	}
-	// Clears the VM from being busy.
-	defer vms.clearDiskBusy(vm)
-
-	// Creates the template.
-	template, err := newTemplate(name, owner, access)
-	if err != nil {
-		return nil, err
-	}
-
-	// Creates the template directory.
-	templateDir := template.getTemplateDir()
-	if err := os.Mkdir(templateDir, 0750); err != nil {
-		msg := "Failed creating template dir: " + err.Error()
-		log.Error(msg)
-		return nil, errors.New(msg)
-	}
-
-	// 1) Copies VM's overlay file into a new one (in the VM's directory!):
-	//    cp disk.qcow disk.tpl.qcow
-	vmDiskFile, _ := filepath.Abs(filepath.Join(vm.dir, vmDiskFile))
-	tplDiskFile, _ := filepath.Abs(filepath.Join(vm.dir, "/disk.tpl.qcow"))
-	if err := utils.CopyFiles(vmDiskFile, tplDiskFile); err != nil {
-		template.delete()
-		GetVMsInstance().updateVM(vm)
-		log.Error("Failed copying VM overlay disk: " + err.Error())
-		return nil, errors.New("Failed copying VM overlay disk: " + err.Error())
-	}
-
-	// 2) Rebases the new template overlay in order to become a standalone disk file:
-	//    qemu-img rebase -b "" disk.tpl.qcow
-	if err := exec.QemuImgRebase(tplDiskFile); err != nil {
-		template.delete()
-		os.Remove(tplDiskFile)
-		GetVMsInstance().updateVM(vm)
-		return nil, err
-	}
-
-	// 3) Moves the template disk file into the template directory:
-	//    mv disk.tpl.qcow new_template_dir/
-	destFile, _ := filepath.Abs(filepath.Join(templateDir, templateDiskFile))
-	if err := os.Rename(tplDiskFile, destFile); err != nil {
-		template.delete()
-		os.Remove(tplDiskFile)
-		GetVMsInstance().updateVM(vm)
-		log.Error("Failed moving template disk image to final location: " + err.Error())
-		return nil, errors.New("Failed moving template disk image to final location: " + err.Error())
-	}
-
-	return template, nil
+    // Marks the VM to copy from as being busy.
+    if err := vms.setDiskBusy(vm); err != nil {
+        return nil, errors.New("Failed setting disk busy flag during template creation: " + err.Error())
+    }
+    // Clears the VM from being busy.
+    defer vms.clearDiskBusy(vm)
+
+    // Creates the template.
+    template, err := newTemplate(name, owner, access)
+    if err != nil {
+        return nil, err
+    }
+
+    // Creates the template directory.
+    templateDir := template.getTemplateDir()
+    if err := os.Mkdir(templateDir, 0750); err != nil {
+        msg := "Failed creating template dir: " + err.Error()
+        log.Error(msg)
+        return nil, errors.New(msg)
+    }
+
+    // 1) Copies VM's overlay file into a new one (in the VM's directory!):
+    //    cp disk.qcow disk.tpl.qcow
+    vmDiskFile, _ := filepath.Abs(filepath.Join(vm.dir, vmDiskFile))
+    tplDiskFile, _ := filepath.Abs(filepath.Join(vm.dir, "/disk.tpl.qcow"))
+    if err := utils.CopyFiles(vmDiskFile, tplDiskFile); err != nil {
+        template.delete()
+        GetVMsInstance().updateVM(vm)
+        log.Error("Failed copying VM overlay disk: " + err.Error())
+        return nil, errors.New("Failed copying VM overlay disk: " + err.Error())
+    }
+
+    // 2) Rebases the new template overlay in order to become a standalone disk file:
+    //    qemu-img rebase -b "" disk.tpl.qcow
+    if err := exec.QemuImgRebase(tplDiskFile); err != nil {
+        template.delete()
+        os.Remove(tplDiskFile)
+        GetVMsInstance().updateVM(vm)
+        return nil, err
+    }
+
+    // 3) Moves the template disk file into the template directory:
+    //    mv disk.tpl.qcow new_template_dir/
+    destFile, _ := filepath.Abs(filepath.Join(templateDir, templateDiskFile))
+    if err := os.Rename(tplDiskFile, destFile); err != nil {
+        template.delete()
+        os.Remove(tplDiskFile)
+        GetVMsInstance().updateVM(vm)
+        log.Error("Failed moving template disk image to final location: " + err.Error())
+        return nil, errors.New("Failed moving template disk image to final location: " + err.Error())
+    }
+
+    return template, nil
 }
 
 // Creates a template from a qcow file.
 func NewTemplateFromQCOW(name, owner, access, qcowFile string) (*Template, error) {
-	// Creates the template.
-	template, err := newTemplate(name, owner, access)
-	if err != nil {
-		return nil, err
-	}
-
-	// Creates the template directory.
-	templateDir := template.getTemplateDir()
-	if err := os.Mkdir(templateDir, 0750); err != nil {
-		log.Error("Failed creating template dir: " + err.Error())
-		return nil, errors.New("Failed creating template dir: " + err.Error())
-	}
-
-	// Moves the qcow file from its location to the template directory.
-	if err := os.Rename(qcowFile, filepath.Join(templateDir, templateDiskFile)); err != nil {
-		log.Error("Failed moving uploaded qcow to template dir: " + err.Error())
-		return nil, errors.New("Failed creating template: " + err.Error())
-	}
-
-	return template, nil
+    // Creates the template.
+    template, err := newTemplate(name, owner, access)
+    if err != nil {
+        return nil, err
+    }
+
+    // Creates the template directory.
+    templateDir := template.getTemplateDir()
+    if err := os.Mkdir(templateDir, 0750); err != nil {
+        log.Error("Failed creating template dir: " + err.Error())
+        return nil, errors.New("Failed creating template dir: " + err.Error())
+    }
+
+    // Moves the qcow file from its location to the template directory.
+    if err := os.Rename(qcowFile, filepath.Join(templateDir, templateDiskFile)); err != nil {
+        log.Error("Failed moving uploaded qcow to template dir: " + err.Error())
+        return nil, errors.New("Failed creating template: " + err.Error())
+    }
+
+    return template, nil
 }
 
 func ValidateTemplateAccess(access string) error {
-	if access != templatePrivate && access != templatePublic {
-		return errors.New("Wrong template access type")
-	}
-	return nil
+    if access != templatePrivate && access != templatePublic {
+        return errors.New("Wrong template access type")
+    }
+    return nil
 }
 
 func (template *Template) IsPublic() bool {
-	return template.Access == templatePublic
+    return template.Access == templatePublic
 }
 
 func (template *Template) GetTemplateDiskPath() string {
-	return filepath.Join(template.getTemplateDir(), templateDiskFile)
+    return filepath.Join(template.getTemplateDir(), templateDiskFile)
 }
 
 // Creates a template.
 func newTemplate(name, owner, access string) (*Template, error) {
-	id, err := uuid.NewRandom()
-	if err != nil {
-		log.Error("Failed creating template: " + err.Error())
-		return nil, err
-	}
+    id, err := uuid.NewRandom()
+    if err != nil {
+        log.Error("Failed creating template: " + err.Error())
+        return nil, err
+    }
 
-	template := &Template{id, name, owner, access, time.Now()}
+    template := &Template{id, name, owner, access, time.Now()}
 
-	if err := template.validate(); err != nil {
-		return nil, errors.New("Failed validating template: " + err.Error())
-	}
+    if err := template.validate(); err != nil {
+        return nil, errors.New("Failed validating template: " + err.Error())
+    }
 
-	return template, nil
+    return template, nil
 }
 
 // Creates a template from a templateConfFile and returns it.
 func newTemplateFromFile(file string) (*Template, error) {
-	filein, err := os.OpenFile(file, os.O_RDONLY, 0)
-	if err != nil {
-		return nil, errors.New("Failed reading template config file: " + err.Error())
-	}
-	defer filein.Close()
-
-	// Decodes the json file into users, then checks:
-	// - all fields are present
-	// - extra fields are not allowed
-	decoder := json.NewDecoder(filein)
-	decoder.DisallowUnknownFields()
-	template := &Template{}
-	if err = decoder.Decode(&template); err != nil {
-		return nil, errors.New("Failed decoding template config file: " + err.Error())
-	}
-
-	if err = template.validate(); err != nil {
-		return nil, errors.New("Failed validating template config file: " + err.Error())
-	}
-
-	return template, nil
+    filein, err := os.OpenFile(file, os.O_RDONLY, 0)
+    if err != nil {
+        return nil, errors.New("Failed reading template config file: " + err.Error())
+    }
+    defer filein.Close()
+
+    // Decodes the json file into users, then checks:
+    // - all fields are present
+    // - extra fields are not allowed
+    decoder := json.NewDecoder(filein)
+    decoder.DisallowUnknownFields()
+    template := &Template{}
+    if err = decoder.Decode(&template); err != nil {
+        return nil, errors.New("Failed decoding template config file: " + err.Error())
+    }
+
+    if err = template.validate(); err != nil {
+        return nil, errors.New("Failed validating template config file: " + err.Error())
+    }
+
+    return template, nil
 }
 
 // Writes a template's config file.
 func (template *Template) writeConfig() error {
-	templateDir := template.getTemplateDir()
-	templateConfigFile := filepath.Join(templateDir, templateConfFile)
-
-	file, err := os.Create(templateConfigFile)
-	if err != nil {
-		template.delete()
-		log.Error("Failed writing template config file: " + err.Error())
-		return errors.New("Failed writing template config file: " + err.Error())
-	}
-	defer file.Close()
-	encoder := json.NewEncoder(file)
-	encoder.SetIndent("", "    ")
-	if err = encoder.Encode(template); err != nil {
-		template.delete()
-		log.Error("Failed encoding template config file: " + err.Error())
-		return errors.New("Failed encoding template config file: " + err.Error())
-	}
-
-	return nil
+    templateDir := template.getTemplateDir()
+    templateConfigFile := filepath.Join(templateDir, templateConfFile)
+
+    file, err := os.Create(templateConfigFile)
+    if err != nil {
+        template.delete()
+        log.Error("Failed writing template config file: " + err.Error())
+        return errors.New("Failed writing template config file: " + err.Error())
+    }
+    defer file.Close()
+    encoder := json.NewEncoder(file)
+    encoder.SetIndent("", "    ")
+    if err = encoder.Encode(template); err != nil {
+        template.delete()
+        log.Error("Failed encoding template config file: " + err.Error())
+        return errors.New("Failed encoding template config file: " + err.Error())
+    }
+
+    return nil
 }
 
 // Checks the template's fields are valid.
 func (template *Template) validate() error {
-	validate := validator.New()
-	if err := validate.Struct(template); err != nil {
-		return err
-	}
+    validate := validator.New()
+    if err := validate.Struct(template); err != nil {
+        return err
+    }
 
-	return ValidateTemplateAccess(template.Access)
+    return ValidateTemplateAccess(template.Access)
 }
 
 // Deletes a template's directory and its content.
 func (template *Template) delete() error {
-	templateDir := template.getTemplateDir()
-	if err := os.RemoveAll(templateDir); err != nil {
-		log.Error("Failed deleting template files: " + err.Error())
-		return errors.New("Failed deleting template files: " + err.Error())
-	}
+    templateDir := template.getTemplateDir()
+    if err := os.RemoveAll(templateDir); err != nil {
+        log.Error("Failed deleting template files: " + err.Error())
+        return errors.New("Failed deleting template files: " + err.Error())
+    }
 
-	return nil
+    return nil
 }
 
 func (template *Template) getTemplateDir() string {
-	templatesDir := GetTemplatesInstance().getDir()
-	return filepath.Join(templatesDir, template.ID.String())
+    templatesDir := GetTemplatesInstance().getDir()
+    return filepath.Join(templatesDir, template.ID.String())
 }
diff --git a/src/vms/templates.go b/src/vms/templates.go
index ad1002711cabea53693f82212e7968d10882471f..ba92387f6760dd47024e6004d11aa7500b69c552 100644
--- a/src/vms/templates.go
+++ b/src/vms/templates.go
@@ -1,25 +1,25 @@
 package vms
 
 import(
-	"os"
-	"sort"
-	"path"
-	"sync"
-	"errors"
-	"path/filepath"
-	"nexus-server/paths"
-	"nexus-server/utils"
-	"github.com/google/uuid"
+    "os"
+    "sort"
+    "path"
+    "sync"
+    "errors"
+    "path/filepath"
+    "nexus-server/paths"
+    "nexus-server/utils"
+    "github.com/google/uuid"
 )
 
 type (
-	TemplateKeeperFn func(tpl Template) bool
+    TemplateKeeperFn func(tpl Template) bool
 
-	Templates struct {
-		m map[string]Template
-		dir string            // Base directory where templates reside
-		rwlock *sync.RWMutex
-	}
+    Templates struct {
+        m map[string]Template
+        dir string            // Base directory where templates reside
+        rwlock *sync.RWMutex
+    }
 )
 
 var templates *Templates
@@ -27,76 +27,76 @@ var templates *Templates
 // Returns a Templates "singleton".
 // IMPORTANT: the InitTemplates function must have been previously called!
 func GetTemplatesInstance() *Templates {
-	return templates
+    return templates
 }
 
 // Create all templates from on-disk files.
 // NOTE: path is the root directory where templates reside.
 func InitTemplates() error {
-	templatesDir := paths.GetInstance().TemplatesDir
-	templates = &Templates { m: make(map[string]Template), dir: templatesDir, rwlock: new(sync.RWMutex) }
-
-	dirs, err := utils.GetSubDirs(templatesDir)
-	if err != nil {
-		return errors.New("Failed reading templates directory: "+err.Error())
-	}
-
-	for _, dir := range(dirs) {
-		// Checks the template directory is valid.
-		templateDir := path.Base(dir)
-		_, err := uuid.Parse(templateDir)
-		if err != nil {
-			log.Warn("Skipping template "+templateDir+": invalid directory name")
-			continue
-		}
-
-		// Checks that a templateDiskFile is present
-		if _, err := os.Stat(filepath.Join(dir, templateDiskFile)); err != nil {
-			log.Warn("Skipping template "+templateDir+": missing "+templateDiskFile)
-			continue
-		}
-
-		// Read and validate the template's content
-		template, err := newTemplateFromFile(filepath.Join(dir, templateConfFile))
-		if err != nil {
-			log.Warn("Skipping template "+templateDir+": "+err.Error())
-			continue
-		}
-
-		templates.m[templateDir] = *template
-	}
-
-	return nil
+    templatesDir := paths.GetInstance().TemplatesDir
+    templates = &Templates { m: make(map[string]Template), dir: templatesDir, rwlock: new(sync.RWMutex) }
+
+    dirs, err := utils.GetSubDirs(templatesDir)
+    if err != nil {
+        return errors.New("Failed reading templates directory: "+err.Error())
+    }
+
+    for _, dir := range(dirs) {
+        // Checks the template directory is valid.
+        templateDir := path.Base(dir)
+        _, err := uuid.Parse(templateDir)
+        if err != nil {
+            log.Warn("Skipping template "+templateDir+": invalid directory name")
+            continue
+        }
+
+        // Checks that a templateDiskFile is present
+        if _, err := os.Stat(filepath.Join(dir, templateDiskFile)); err != nil {
+            log.Warn("Skipping template "+templateDir+": missing "+templateDiskFile)
+            continue
+        }
+
+        // Read and validate the template's content
+        template, err := newTemplateFromFile(filepath.Join(dir, templateConfFile))
+        if err != nil {
+            log.Warn("Skipping template "+templateDir+": "+err.Error())
+            continue
+        }
+
+        templates.m[templateDir] = *template
+    }
+
+    return nil
 }
 
 // Returns the list of templates for which TemplateKeeperFn returns true.
 func (templates *Templates)GetTemplates(keep TemplateKeeperFn) []Template {
-	templates.rwlock.RLock()
-	list := []Template{}
-	for _, t := range templates.m {
-		if keep(t) {
-			list = append(list, t)
-		}
-	}
-	templates.rwlock.RUnlock()
-
-	// Sort templates by names
-	sort.Slice(list, func(i, j int) bool {
+    templates.rwlock.RLock()
+    list := []Template{}
+    for _, t := range templates.m {
+        if keep(t) {
+            list = append(list, t)
+        }
+    }
+    templates.rwlock.RUnlock()
+
+    // Sort templates by names
+    sort.Slice(list, func(i, j int) bool {
         return list[i].Name < list[j].Name
     })
-	return list
+    return list
 }
 
 // Returns a template by its ID.
 func (templates *Templates)GetTemplate(tplID uuid.UUID) (Template, error) {
-	templates.rwlock.RLock()
-	defer templates.rwlock.RUnlock()
-
-	template, exists := templates.m[tplID.String()]
-	if !exists {
-		return dummyTemplate, errors.New("Template not found")
-	}
-	return template, nil
+    templates.rwlock.RLock()
+    defer templates.rwlock.RUnlock()
+
+    template, exists := templates.m[tplID.String()]
+    if !exists {
+        return dummyTemplate, errors.New("Template not found")
+    }
+    return template, nil
 }
 
 // Deletes a template by its ID.
@@ -104,73 +104,73 @@ func (templates *Templates)GetTemplate(tplID uuid.UUID) (Template, error) {
 // TODO: prevents deletion if the template's disk image is
 //       being exported by RouterTemplates.ExportDisk
 func (templates *Templates)DeleteTemplate(tplID uuid.UUID, vms *VMs) error {
-	id := tplID.String()
-	templates.rwlock.Lock()
-	defer templates.rwlock.Unlock()
-	template, exists := templates.m[id]
-	if exists {
-		if vms.IsTemplateUsed(id) {
-			return errors.New("Failed deleting template: still used by one or more VMs")
-		}
-		// Removes the template's files (and directory).
-		if err := template.delete(); err != nil {
-			return err
-		}
-		// Removes the template from the map.
-		delete(templates.m, id)
-		return nil
-	}
-
-	return errors.New("Template not found")
+    id := tplID.String()
+    templates.rwlock.Lock()
+    defer templates.rwlock.Unlock()
+    template, exists := templates.m[id]
+    if exists {
+        if vms.IsTemplateUsed(id) {
+            return errors.New("Failed deleting template: still used by one or more VMs")
+        }
+        // Removes the template's files (and directory).
+        if err := template.delete(); err != nil {
+            return err
+        }
+        // Removes the template from the map.
+        delete(templates.m, id)
+        return nil
+    }
+
+    return errors.New("Template not found")
 }
 
 // Adds a template and writes its config file.
 func (templates *Templates)AddTemplate(template *Template) error {
-	templates.rwlock.Lock()
-	defer templates.rwlock.Unlock()
+    templates.rwlock.Lock()
+    defer templates.rwlock.Unlock()
 
-	err := template.writeConfig()
-	if err != nil {
-		return err
-	}
+    err := template.writeConfig()
+    if err != nil {
+        return err
+    }
 
-	// Adds template to the map of templates.
-	templates.m[template.ID.String()] = *template
+    // Adds template to the map of templates.
+    templates.m[template.ID.String()] = *template
 
-	return nil
+    return nil
 }
 
 func (templates *Templates)getDir() string {
-	return templates.dir
+    return templates.dir
 }
 
 // Edit a template' specs: name, access
 func (templates *Templates)EditTemplate(tplID uuid.UUID, name, access string) error {
-	tpl, err := templates.GetTemplate(tplID)
-	if err != nil {
-		return err
-	}
-
-	// Only updates fields that have changed.
-	if name != "" {
-		tpl.Name = name
-	}
-	if access != "" {
-		tpl.Access = access
-	}
-
-	if err = tpl.validate(); err != nil {
-		return err
-	}
-
-	err = tpl.writeConfig()
-	if err != nil {
-		return err
-	}
-
-	key := tpl.ID.String()
-	delete(templates.m, key)
-	templates.m[key] = tpl
-
-	return nil
+    tpl, err := templates.GetTemplate(tplID)
+    if err != nil {
+        return err
+    }
+
+    // Only updates fields that have changed.
+    if name != "" {
+        tpl.Name = name
+    }
+    if access != "" {
+        tpl.Access = access
+    }
+
+    if err = tpl.validate(); err != nil {
+        return err
+    }
+
+    err = tpl.writeConfig()
+    if err != nil {
+        return err
+    }
+
+    key := tpl.ID.String()
+    delete(templates.m, key)
+    templates.m[key] = tpl
+
+    return nil
 }
diff --git a/src/vms/vm.go b/src/vms/vm.go
index f8aaec0d4f17fc84c10fa3134d620b4c28144c6f..ac6ccf0d5a034f6990de0538122954511074e0fc 100644
--- a/src/vms/vm.go
+++ b/src/vms/vm.go
@@ -1,253 +1,253 @@
 package vms
 
 import (
-	"os"
-	"sync"
-	"path"
-	"errors"
-	"syscall"
-	"net/mail"
-	"io/ioutil"
-	"path/filepath"
-	"encoding/json"
-	"encoding/base64"
-	"nexus-server/qga"
-	"nexus-server/caps"
-	"nexus-server/paths"
-	"nexus-server/exec"
-	"github.com/google/uuid"
-	"github.com/go-playground/validator/v10"
-	"github.com/sethvargo/go-password/password"
+    "os"
+    "sync"
+    "path"
+    "errors"
+    "syscall"
+    "net/mail"
+    "io/ioutil"
+    "path/filepath"
+    "encoding/json"
+    "encoding/base64"
+    "nexus-server/qga"
+    "nexus-server/caps"
+    "nexus-server/paths"
+    "nexus-server/exec"
+    "github.com/google/uuid"
+    "github.com/go-playground/validator/v10"
+    "github.com/sethvargo/go-password/password"
 )
 
 type (
-	// Internal VM structure.
-	VM struct {
-		ID uuid.UUID          `json:"id"         validate:"required"`
-		Owner string          `json:"owner"      validate:"required,email"`
-		Name string           `json:"name"       validate:"required,min=2,max=256"`
-		Cpus int              `json:"cpus"       validate:"required,gte=1,lte=16"`
-		Ram int               `json:"ram"        validate:"required,gte=512,lte=32768"`  // in MB
-		Nic NicType           `json:"nic"        validate:"required"`  // "none" or "user"
-		TemplateID uuid.UUID  `json:"templateID" validate:"required"`
-		Access map[string]caps.Capabilities `json:"access"  validate:"required"`
-
-		// None of the fields below are serialized to disk.
-		dir string             // VM directory
-		qgaSock string         // QEMU Guest Agent (QGA) UNIX socket
-		Run runStates
-		DiskBusy bool          // If true the VM's disk is busy (cannot be modified or deleted)
-		mutex *sync.Mutex
-	}
-
-	runStates struct {
-		State VMState
-		Pid int
-		Port int
-		Pwd string
-	}
-
-	VMState string
-	NicType string
-
-	// VM fields to be serialized to disk.
-	VMDiskSerialized struct {
-		ID uuid.UUID           `json:"id"`
-		Owner string           `json:"owner"`
-		Name string            `json:"name"`
-		Cpus int               `json:"cpus"`
-		Ram int                `json:"ram"`  // in MB
-		Nic NicType            `json:"nic"`
-		TemplateID uuid.UUID   `json:"templateID"`
-		Access map[string]caps.Capabilities `json:"access"`
-	}
-
-	// VM fields to be serialized over the network (sent to the client).
-	VMNetworkSerialized struct {
-		ID uuid.UUID
-		Owner string
-		Name string
-		Cpus int
-		Ram int
-		Nic NicType
-		TemplateID uuid.UUID
-		Access map[string]caps.Capabilities
-		State VMState
-		Port int
-		Pwd string
-		DiskBusy bool          // If true the VM's disk is busy (cannot be modified or deleted)
-	}
-
-	endOfExecCallback func(vm *VM)
+    // Internal VM structure.
+    VM struct {
+        ID uuid.UUID          `json:"id"         validate:"required"`
+        Owner string          `json:"owner"      validate:"required,email"`
+        Name string           `json:"name"       validate:"required,min=2,max=256"`
+        Cpus int              `json:"cpus"       validate:"required,gte=1,lte=16"`
+        Ram int               `json:"ram"        validate:"required,gte=512,lte=32768"`  // in MB
+        Nic NicType           `json:"nic"        validate:"required"`  // "none" or "user"
+        TemplateID uuid.UUID  `json:"templateID" validate:"required"`
+        Access map[string]caps.Capabilities `json:"access"  validate:"required"`
+
+        // None of the fields below are serialized to disk.
+        dir string             // VM directory
+        qgaSock string         // QEMU Guest Agent (QGA) UNIX socket
+        Run runStates
+        DiskBusy bool          // If true the VM's disk is busy (cannot be modified or deleted)
+        mutex *sync.Mutex
+    }
+
+    runStates struct {
+        State VMState
+        Pid int
+        Port int
+        Pwd string
+    }
+
+    VMState string
+    NicType string
+
+    // VM fields to be serialized to disk.
+    VMDiskSerialized struct {
+        ID uuid.UUID           `json:"id"`
+        Owner string           `json:"owner"`
+        Name string            `json:"name"`
+        Cpus int               `json:"cpus"`
+        Ram int                `json:"ram"`  // in MB
+        Nic NicType            `json:"nic"`
+        TemplateID uuid.UUID   `json:"templateID"`
+        Access map[string]caps.Capabilities `json:"access"`
+    }
+
+    // VM fields to be serialized over the network (sent to the client).
+    VMNetworkSerialized struct {
+        ID uuid.UUID
+        Owner string
+        Name string
+        Cpus int
+        Ram int
+        Nic NicType
+        TemplateID uuid.UUID
+        Access map[string]caps.Capabilities
+        State VMState
+        Port int
+        Pwd string
+        DiskBusy bool          // If true the VM's disk is busy (cannot be modified or deleted)
+    }
+
+    endOfExecCallback func(vm *VM)
 )
 
 const (
-	vmDiskFile     = "disk.qcow"
-	vmConfFile     = "vm.json"
-	vmSecretFile   = "secret"
-	vmQGASockFile  = "qga.sock"
+    vmDiskFile     = "disk.qcow"
+    vmConfFile     = "vm.json"
+    vmSecretFile   = "secret"
+    vmQGASockFile  = "qga.sock"
 
-	nicUser NicType = "user"
-	nicNone NicType = "none"
+    nicUser NicType = "user"
+    nicNone NicType = "none"
 
-	stateStopped VMState  = "STOPPED"
-	stateRunning          = "RUNNING"
+    stateStopped VMState  = "STOPPED"
+    stateRunning          = "RUNNING"
 )
 
 var dummyVM = VM{}
 
 // Custom password generator with the following characters removed: 0, O, l, I
 var passwordGen, _ = password.NewGenerator(&password.GeneratorInput{
-	LowerLetters: "abcdefghijkmnopqrstuvwxyz",
-	UpperLetters: "ABCDEFGHJKLMNPQRSTUVWXYZ",
-	Digits: "123456789",
+    LowerLetters: "abcdefghijkmnopqrstuvwxyz",
+    UpperLetters: "ABCDEFGHJKLMNPQRSTUVWXYZ",
+    Digits: "123456789",
 })
 
 // Creates a VM.
 func NewVM(creatorEmail string, name string, cpus, ram int, nic NicType, templateID uuid.UUID, owner string) (*VM, error) {
-	vmID, err := uuid.NewRandom()
-
-	if err != nil {
-		log.Error("Failed creating VM: "+err.Error())
-		return nil, err
-	}
-	vm := newEmptyVM()
-	vm.ID = vmID
-	vm.Owner = owner
-	vm.Name = name
-	vm.Cpus = cpus
-	vm.Ram = ram
-	vm.Nic = nic
-	vm.TemplateID = templateID
-	id := vmID.String()
-	vm.dir = filepath.Join(vms.dir, id[0:3], id[3:6], id)
-	vm.qgaSock = filepath.Join(vm.dir, vmQGASockFile)
-	vm.Access = make(map[string]caps.Capabilities)
-
-	if err = vm.validate(); err != nil {
-		return nil, errors.New("Failed validating VM: "+err.Error())
-	}
-
-	return vm, nil
+    vmID, err := uuid.NewRandom()
+
+    if err != nil {
+        log.Error("Failed creating VM: "+err.Error())
+        return nil, err
+    }
+    vm := newEmptyVM()
+    vm.ID = vmID
+    vm.Owner = owner
+    vm.Name = name
+    vm.Cpus = cpus
+    vm.Ram = ram
+    vm.Nic = nic
+    vm.TemplateID = templateID
+    id := vmID.String()
+    vm.dir = filepath.Join(vms.dir, id[0:3], id[3:6], id)
+    vm.qgaSock = filepath.Join(vm.dir, vmQGASockFile)
+    vm.Access = make(map[string]caps.Capabilities)
+
+    if err = vm.validate(); err != nil {
+        return nil, errors.New("Failed validating VM: "+err.Error())
+    }
+
+    return vm, nil
 }
 
 func (vm *VM)SerializeToDisk() VMDiskSerialized {
-	return VMDiskSerialized {
-		ID: vm.ID,
-		Owner: vm.Owner,
-		Name: vm.Name,
-		Cpus: vm.Cpus,
-		Ram: vm.Ram,
-		Nic: vm.Nic,
-		TemplateID: vm.TemplateID,
-		Access: vm.Access,
-	}
+    return VMDiskSerialized {
+        ID: vm.ID,
+        Owner: vm.Owner,
+        Name: vm.Name,
+        Cpus: vm.Cpus,
+        Ram: vm.Ram,
+        Nic: vm.Nic,
+        TemplateID: vm.TemplateID,
+        Access: vm.Access,
+    }
 }
 
 func (vm *VM)SerializeToNetwork() VMNetworkSerialized {
-	return VMNetworkSerialized {
-		ID: vm.ID,
-		Owner: vm.Owner,
-		Name: vm.Name,
-		Cpus: vm.Cpus,
-		Ram: vm.Ram,
-		Nic: vm.Nic,
-		TemplateID: vm.TemplateID,
-		Access: vm.Access,
-		State: vm.Run.State,
-		Port: vm.Run.Port,
-		Pwd: vm.Run.Pwd,
-		DiskBusy: vm.DiskBusy,
-	}
+    return VMNetworkSerialized {
+        ID: vm.ID,
+        Owner: vm.Owner,
+        Name: vm.Name,
+        Cpus: vm.Cpus,
+        Ram: vm.Ram,
+        Nic: vm.Nic,
+        TemplateID: vm.TemplateID,
+        Access: vm.Access,
+        State: vm.Run.State,
+        Port: vm.Run.Port,
+        Pwd: vm.Run.Pwd,
+        DiskBusy: vm.DiskBusy,
+    }
 }
 
 func (vm *VM)getDiskPath() string {
-	vmDiskFile, _ := filepath.Abs(filepath.Join(vm.dir, vmDiskFile))
-	return vmDiskFile
+    vmDiskFile, _ := filepath.Abs(filepath.Join(vm.dir, vmDiskFile))
+    return vmDiskFile
 }
 
 // Returns true if the specified email is the VM's owner.
 func (vm *VM)IsOwner(email string) bool {
-	return email == vm.Owner
+    return email == vm.Owner
 }
 
 // Creates an empty VM.
 func newEmptyVM() *VM {
-	return &VM {
-		ID: uuid.Nil,
-		Owner: "",
-		Name: "",
-		Cpus: 0,
-		Ram: 0,
-		Nic: "",
-		TemplateID: uuid.Nil,
-		Access: make(map[string]caps.Capabilities),
-
-		dir: "",
-		qgaSock: "",
-		Run: runStates { State: stateStopped, Pid: 0, Port: 0, Pwd: "" },
-		DiskBusy: false,
-		mutex: new(sync.Mutex),
-	}
+    return &VM {
+        ID: uuid.Nil,
+        Owner: "",
+        Name: "",
+        Cpus: 0,
+        Ram: 0,
+        Nic: "",
+        TemplateID: uuid.Nil,
+        Access: make(map[string]caps.Capabilities),
+
+        dir: "",
+        qgaSock: "",
+        Run: runStates { State: stateStopped, Pid: 0, Port: 0, Pwd: "" },
+        DiskBusy: false,
+        mutex: new(sync.Mutex),
+    }
 }
 
 // Creates a VM from a vmConfFile and returns it.
 func newVMFromFile(vmFile string) (*VM, error) {
-	filein, err := os.OpenFile(vmFile, os.O_RDONLY, 0)
-	if err != nil {
+    filein, err := os.OpenFile(vmFile, os.O_RDONLY, 0)
+    if err != nil {
         return nil, errors.New("Failed reading VM config file: "+err.Error())
-	}
-	defer filein.Close()
-
-	// Decodes and validates the json file 
-	decoder := json.NewDecoder(filein)
-	decoder.DisallowUnknownFields()
-	vm := newEmptyVM()
-	if err = decoder.Decode(&vm); err != nil {
-		return nil, errors.New("Failed decoding VM config file: "+err.Error())
-	}
-
-	if err = vm.validate(); err != nil {
-		return nil, errors.New("Failed validating VM: "+err.Error())
-	}
-
-	vm.dir = path.Dir(vmFile)
-	vm.qgaSock = filepath.Join(vm.dir, vmQGASockFile)
-	return vm, nil
+    }
+    defer filein.Close()
+
+    // Decodes and validates the json file
+    decoder := json.NewDecoder(filein)
+    decoder.DisallowUnknownFields()
+    vm := newEmptyVM()
+    if err = decoder.Decode(&vm); err != nil {
+        return nil, errors.New("Failed decoding VM config file: "+err.Error())
+    }
+
+    if err = vm.validate(); err != nil {
+        return nil, errors.New("Failed validating VM: "+err.Error())
+    }
+
+    vm.dir = path.Dir(vmFile)
+    vm.qgaSock = filepath.Join(vm.dir, vmQGASockFile)
+    return vm, nil
 }
 
 func (vm *VM)IsRunning() bool {
-	return vm.Run.State == stateRunning
+    return vm.Run.State == stateRunning
 }
 
 // Checks that the VM structure's fields are valid.
 func (vm *VM)validate() error {
-	// Checks the capabilities are valid
-	for email, accessCaps := range vm.Access {
-		_, err := mail.ParseAddress(email)
-		if err != nil {
-			return errors.New("Invalid email")
-		}
-		if err := caps.ValidateVMAccessCaps(accessCaps); err != nil {
-			return err
-		}
-	}
-
-	if (vm.Nic != nicNone && vm.Nic != nicUser) {
-		return errors.New("Invalid nic value: "+string(vm.Nic))
-	}
-
-	if err := validator.New().Struct(vm); err != nil {
-		return err
-	}
-
-	// Checks that the template referenced by the VM actually exists.
-	_, err := GetTemplatesInstance().GetTemplate(vm.TemplateID)
-	if err != nil {
-		return err
-	}
-
-	return nil
+    // Checks the capabilities are valid
+    for email, accessCaps := range vm.Access {
+        _, err := mail.ParseAddress(email)
+        if err != nil {
+            return errors.New("Invalid email")
+        }
+        if err := caps.ValidateVMAccessCaps(accessCaps); err != nil {
+            return err
+        }
+    }
+
+    if (vm.Nic != nicNone && vm.Nic != nicUser) {
+        return errors.New("Invalid nic value: "+string(vm.Nic))
+    }
+
+    if err := validator.New().Struct(vm); err != nil {
+        return err
+    }
+
+    // Checks that the template referenced by the VM actually exists.
+    _, err := GetTemplatesInstance().GetTemplate(vm.TemplateID)
+    if err != nil {
+        return err
+    }
+
+    return nil
 }
 
 // Writes a VM's files:
@@ -255,251 +255,251 @@ func (vm *VM)validate() error {
 // 2) Writes vmConfFile.
 // 3) Creates vmDiskFile as an overlay on top of the template disk.
 func (vm *VM)writeFiles() error {
-	// Checks the template referenced by the VM exists.
-	template, err := GetTemplatesInstance().GetTemplate(vm.TemplateID)
-	if err != nil {
-		return err
-	}
-
-	// Creates the 3-directory structure.
-	if err = os.MkdirAll(vm.dir, 0750); err != nil {
-		log.Error("Failed creating VM dirs: "+err.Error())
-		return errors.New("Failed creating VM dirs: "+err.Error())
-	}
-
-	// Writes vmConfFile.
-	if err = vm.writeConfig(); err != nil {
-		return err
-	}
-
-	// Creates vmDiskFile as an overlay on top of the template disk.
-	// NOTE: template and output file must be both specified as absolute paths.
-	templateDiskFile, _ := filepath.Abs(filepath.Join(GetTemplatesInstance().getDir(), template.ID.String(), templateDiskFile))
-
-	if err := exec.QemuImgCreate(templateDiskFile, vm.getDiskPath()); err != nil {
-		vm.delete()
-		return err
-	}
-
-	return nil
+    // Checks the template referenced by the VM exists.
+    template, err := GetTemplatesInstance().GetTemplate(vm.TemplateID)
+    if err != nil {
+        return err
+    }
+
+    // Creates the 3-directory structure.
+    if err = os.MkdirAll(vm.dir, 0750); err != nil {
+        log.Error("Failed creating VM dirs: "+err.Error())
+        return errors.New("Failed creating VM dirs: "+err.Error())
+    }
+
+    // Writes vmConfFile.
+    if err = vm.writeConfig(); err != nil {
+        return err
+    }
+
+    // Creates vmDiskFile as an overlay on top of the template disk.
+    // NOTE: template and output file must be both specified as absolute paths.
+    templateDiskFile, _ := filepath.Abs(filepath.Join(GetTemplatesInstance().getDir(), template.ID.String(), templateDiskFile))
+
+    if err := exec.QemuImgCreate(templateDiskFile, vm.getDiskPath()); err != nil {
+        vm.delete()
+        return err
+    }
+
+    return nil
 }
 
 // Writes the VM config file (vmConfFile).
 // NOTE: does not check the template's validity!
 func (vm *VM)writeConfig() error {
-	vmFile := filepath.Join(vm.dir, vmConfFile)
-	 file, err := os.Create(vmFile)
-	 if err != nil {
-		 log.Error("Failed writing VM config file: "+err.Error())
+    vmFile := filepath.Join(vm.dir, vmConfFile)
+     file, err := os.Create(vmFile)
+     if err != nil {
+         log.Error("Failed writing VM config file: "+err.Error())
         return errors.New("Failed writing VM config file: "+err.Error())
-	}
-	defer file.Close()
-	encoder := json.NewEncoder(file)
-	encoder.SetIndent("", "    ")
+    }
+    defer file.Close()
+    encoder := json.NewEncoder(file)
+    encoder.SetIndent("", "    ")
 
-	if err = encoder.Encode(vm.SerializeToDisk()); err != nil {
-		log.Error("Failed encoding VM config file: "+err.Error())
-		return errors.New("Failed encoding VM config file: "+err.Error())
-	}
+    if err = encoder.Encode(vm.SerializeToDisk()); err != nil {
+        log.Error("Failed encoding VM config file: "+err.Error())
+        return errors.New("Failed encoding VM config file: "+err.Error())
+    }
 
-	return nil
+    return nil
 }
 
 // Deletes the files associated to a VM.
 // The VM must be stopped before being deleted, otherwise an error is returned.
 func (vm *VM)delete() error {
-	if vm.IsRunning() {
-		return errors.New("Failed deleting VM: VM must be stopped")
-	}
+    if vm.IsRunning() {
+        return errors.New("Failed deleting VM: VM must be stopped")
+    }
 
-	if vm.DiskBusy {
-		return errors.New("Failed deleting VM: disk is busy")
-	}
+    if vm.DiskBusy {
+        return errors.New("Failed deleting VM: disk is busy")
+    }
 
-	// Deletes the VM's directory and its content.
-	if err := os.RemoveAll(vm.dir); err != nil {
-		log.Error("Failed deleting VM files: "+err.Error())
+    // Deletes the VM's directory and its content.
+    if err := os.RemoveAll(vm.dir); err != nil {
+        log.Error("Failed deleting VM files: "+err.Error())
         return errors.New("Failed deleting VM files: "+err.Error())
-	}
-
-	// Deletes parents directories if they are empty.
-	// Directories are only deleted if empty (otherwise an error is triggered which we ignore).
-	parentDir := path.Dir(vm.dir)
-	parentParentDir := path.Dir(parentDir)
-	os.Remove(parentDir)
-	os.Remove(parentParentDir)
-	return nil
+    }
+
+    // Deletes parents directories if they are empty.
+    // Directories are only deleted if empty (otherwise an error is triggered which we ignore).
+    parentDir := path.Dir(vm.dir)
+    parentParentDir := path.Dir(parentDir)
+    os.Remove(parentDir)
+    os.Remove(parentParentDir)
+    return nil
 }
 
 // Starts a VM and returns the access password.
 // Password is randomly generated.
 func (vm *VM)start(port int, endofExecFn endOfExecCallback) (string, error) {
-	if vm.IsRunning() {
-		return "", errors.New("Failed starting VM: VM is already running")
-	}
-
-	if vm.DiskBusy {
-		return "", errors.New("Failed starting VM: disk is busy")
-	}
-
-	// Generates a 8 characters long password with 4 digits, 0 symbols,
-	// allowing upper and lower case letters, disallowing repeat characters.
-	pwd, err := passwordGen.Generate(8, 4, 0, false, false)
-	if err != nil {
-		log.Error("Failed starting VM, password generation error: "+err.Error())
-		return "", errors.New("Failed starting VM, password generation error: "+err.Error())
-	}
-
-	// Writes the password in a "secret" file.
-	pwdFile, err := vm.writeSecretFile(pwd)
-	if err != nil {
-		log.Error("Failed starting VM, error creating secret file: "+err.Error())
-		return "", errors.New("Failed starting VM, error creating secret file: "+err.Error())
-	}
-
-	if err = vm.runQEMU(port, pwd, pwdFile, endofExecFn); err != nil {
-		vm.removeSecretFile()
-		os.Remove(vm.qgaSock)  // If QEMU fails it's likely the Guest Agent file it created is still there.
-		return "", errors.New("Failed starting VM, error running QEMU: "+err.Error())
-	}
-
-	return pwd, nil
+    if vm.IsRunning() {
+        return "", errors.New("Failed starting VM: VM is already running")
+    }
+
+    if vm.DiskBusy {
+        return "", errors.New("Failed starting VM: disk is busy")
+    }
+
+    // Generates a 8 characters long password with 4 digits, 0 symbols,
+    // allowing upper and lower case letters, disallowing repeat characters.
+    pwd, err := passwordGen.Generate(8, 4, 0, false, false)
+    if err != nil {
+        log.Error("Failed starting VM, password generation error: "+err.Error())
+        return "", errors.New("Failed starting VM, password generation error: "+err.Error())
+    }
+
+    // Writes the password in a "secret" file.
+    pwdFile, err := vm.writeSecretFile(pwd)
+    if err != nil {
+        log.Error("Failed starting VM, error creating secret file: "+err.Error())
+        return "", errors.New("Failed starting VM, error creating secret file: "+err.Error())
+    }
+
+    if err = vm.runQEMU(port, pwd, pwdFile, endofExecFn); err != nil {
+        vm.removeSecretFile()
+        os.Remove(vm.qgaSock)  // If QEMU fails it's likely the Guest Agent file it created is still there.
+        return "", errors.New("Failed starting VM, error running QEMU: "+err.Error())
+    }
+
+    return pwd, nil
 }
 
 // Writes the specified password in Base64 in a "secret" file inside the VM directory.
 // Returns the file that was written if success.
 func (vm *VM)writeSecretFile(pwd string) (string, error) {
-	// Write the password in a "secret" file inside the VM directory.
-	pwdBase64 := base64.StdEncoding.EncodeToString([]byte(pwd))
-	content := []byte(pwdBase64)
-	pwdFile := filepath.Join(vm.dir, vmSecretFile)
-	if err := ioutil.WriteFile(pwdFile, content, 0600); err != nil {
-		return "", err
-	}
-	return pwdFile, nil
+    // Write the password in a "secret" file inside the VM directory.
+    pwdBase64 := base64.StdEncoding.EncodeToString([]byte(pwd))
+    content := []byte(pwdBase64)
+    pwdFile := filepath.Join(vm.dir, vmSecretFile)
+    if err := ioutil.WriteFile(pwdFile, content, 0600); err != nil {
+        return "", err
+    }
+    return pwdFile, nil
 }
 
 func (vm *VM)removeSecretFile() {
-	pwdFile := filepath.Join(vm.dir, vmSecretFile)
-	os.Remove(pwdFile)
+    pwdFile := filepath.Join(vm.dir, vmSecretFile)
+    os.Remove(pwdFile)
 }
 
 // Kills by force a running VM.
 func (vm *VM)kill() error {
-	if !vm.IsRunning() {
-		return errors.New("Failed stopping VM: VM is not running")
-	}
-
-	// Sends a SIGINT signal to terminate the QEMU process.
-	// Note that QEMU terminates with status code 0 in this case (i.e. no error).
-	if err := syscall.Kill(vm.Run.Pid, syscall.SIGINT); err != nil {
-		log.Error("Failed stopping VM: "+err.Error())
-		return errors.New("Failed stopping VM: "+err.Error())
-	}
-
-	return nil
+    if !vm.IsRunning() {
+        return errors.New("Failed stopping VM: VM is not running")
+    }
+
+    // Sends a SIGINT signal to terminate the QEMU process.
+    // Note that QEMU terminates with status code 0 in this case (i.e. no error).
+    if err := syscall.Kill(vm.Run.Pid, syscall.SIGINT); err != nil {
+        log.Error("Failed stopping VM: "+err.Error())
+        return errors.New("Failed stopping VM: "+err.Error())
+    }
+
+    return nil
 }
 
 // Gracefully shutdowns a running VM.
 // Uses QGA commands to talk to the VM, which means QEMU Guest Agent must be
 // running in the VM, otherwise it won't work.
 func (vm *VM)shutdown() error {
-	prefix := "Shutdown failed: "
-
-	if !vm.IsRunning() {
-		return errors.New(prefix+"VM is not running")
-	}
-
-	if vm.DiskBusy {
-		return errors.New(prefix+"VM disk is busy")
-	}
-
-	// Sends a QGA command to order the VM to shutdown.
-	con := qga.New()
-	if err := con.Open(vm.qgaSock); err != nil {
-		log.Error(prefix+"(open): "+err.Error())
-		return errors.New(prefix+"(open): "+err.Error())
-	}	
-
-	if err := con.SendShutdown(); err != nil {
-		con.Close()
-		log.Error(prefix+"(send): "+err.Error())
-		return errors.New(prefix+"(send): "+err.Error())
-	}
-
-	if err := con.Close(); err != nil {
-		log.Error(prefix+"(close): "+err.Error())
-		return errors.New(prefix+"(close): "+err.Error())
-	}
-
-	return nil
+    prefix := "Shutdown failed: "
+
+    if !vm.IsRunning() {
+        return errors.New(prefix+"VM is not running")
+    }
+
+    if vm.DiskBusy {
+        return errors.New(prefix+"VM disk is busy")
+    }
+
+    // Sends a QGA command to order the VM to shutdown.
+    con := qga.New()
+    if err := con.Open(vm.qgaSock); err != nil {
+        log.Error(prefix+"(open): "+err.Error())
+        return errors.New(prefix+"(open): "+err.Error())
+    }
+
+    if err := con.SendShutdown(); err != nil {
+        con.Close()
+        log.Error(prefix+"(send): "+err.Error())
+        return errors.New(prefix+"(send): "+err.Error())
+    }
+
+    if err := con.Close(); err != nil {
+        log.Error(prefix+"(close): "+err.Error())
+        return errors.New(prefix+"(close): "+err.Error())
+    }
+
+    return nil
 }
 
 // Reboots a running VM.
 // Uses QGA commands to talk to the VM, which means QEMU Guest Agent must be
 // running in the VM, otherwise it won't work.
 func (vm *VM)reboot() error {
-	prefix := "Shutdown failed: "
-
-	if !vm.IsRunning() {
-		return errors.New(prefix+"VM is not running")
-	}
-
-	if vm.DiskBusy {
-		return errors.New(prefix+"VM disk is busy")
-	}
-
-	// Sends a QGA command to order the VM to shutdown.
-	con := qga.New()
-	if err := con.Open(vm.qgaSock); err != nil {
-		log.Error(prefix+"(open): "+err.Error())
-		return errors.New(prefix+"(open): "+err.Error())
-	}
-
-	if err := con.SendReboot(); err != nil {
-		con.Close()
-		log.Error(prefix+"(send): "+err.Error())
-		return errors.New(prefix+"(send): "+err.Error())
-	}
-
-	if err := con.Close(); err != nil {
-		log.Error(prefix+"(close): "+err.Error())
-		return errors.New(prefix+"(close): "+err.Error())
-	}
-
-	return nil
+    prefix := "Shutdown failed: "
+
+    if !vm.IsRunning() {
+        return errors.New(prefix+"VM is not running")
+    }
+
+    if vm.DiskBusy {
+        return errors.New(prefix+"VM disk is busy")
+    }
+
+    // Sends a QGA command to order the VM to shutdown.
+    con := qga.New()
+    if err := con.Open(vm.qgaSock); err != nil {
+        log.Error(prefix+"(open): "+err.Error())
+        return errors.New(prefix+"(open): "+err.Error())
+    }
+
+    if err := con.SendReboot(); err != nil {
+        con.Close()
+        log.Error(prefix+"(send): "+err.Error())
+        return errors.New(prefix+"(send): "+err.Error())
+    }
+
+    if err := con.Close(); err != nil {
+        log.Error(prefix+"(close): "+err.Error())
+        return errors.New(prefix+"(close): "+err.Error())
+    }
+
+    return nil
 }
 
 // Executes the VM in QEMU using the specified spice port and password.
 func (vm *VM)runQEMU(port int, pwd, pwdFile string, endofExecFn endOfExecCallback) error {
-	pkiDir := paths.GetInstance().NexusPkiDir
-	cmd, err := exec.NewQemuSystem(vm.qgaSock, vm.Cpus, vm.Ram, string(vm.Nic), filepath.Join(vm.dir, vmDiskFile), port, pwdFile, pkiDir)
-	if err != nil {
-		return err
-	}
-
-	if err := cmd.Start(); err != nil {
-		log.Error("Failed executing VM "+vm.ID.String()+": exec.Start error: "+err.Error())
-		log.Error("Failed cmd: "+cmd.String())
-		return err
-	}
-
-	vm.Run = runStates { State: stateRunning, Pid: cmd.Process.Pid, Port: port, Pwd: pwd }
-
-	// Execute cmd.Wait() (which is a blocking call) inside a go-routine to avoid blocking.
-	// From here on, there are 2 flows of execution!
-	go func() {
-		if err := cmd.Wait(); err != nil {
-			log.Error("Failed executing VM "+vm.ID.String()+": exec.Wait error: "+err.Error())
-			log.Error("Failed cmd: "+cmd.String())
-		}
-		endofExecFn(vm)
-	} ()
-
-	return nil
+    pkiDir := paths.GetInstance().NexusPkiDir
+    cmd, err := exec.NewQemuSystem(vm.qgaSock, vm.Cpus, vm.Ram, string(vm.Nic), filepath.Join(vm.dir, vmDiskFile), port, pwdFile, pkiDir)
+    if err != nil {
+        return err
+    }
+
+    if err := cmd.Start(); err != nil {
+        log.Error("Failed executing VM "+vm.ID.String()+": exec.Start error: "+err.Error())
+        log.Error("Failed cmd: "+cmd.String())
+        return err
+    }
+
+    vm.Run = runStates { State: stateRunning, Pid: cmd.Process.Pid, Port: port, Pwd: pwd }
+
+    // Execute cmd.Wait() (which is a blocking call) inside a go-routine to avoid blocking.
+    // From here on, there are 2 flows of execution!
+    go func() {
+        if err := cmd.Wait(); err != nil {
+            log.Error("Failed executing VM "+vm.ID.String()+": exec.Wait error: "+err.Error())
+            log.Error("Failed cmd: "+cmd.String())
+        }
+        endofExecFn(vm)
+    } ()
+
+    return nil
 }
 
 // Resets a VM's states.
 func (vm *VM)resetStates() {
-	vm.Run = runStates { State: stateStopped, Pid: 0, Port: 0, Pwd: "" }
+    vm.Run = runStates { State: stateStopped, Pid: 0, Port: 0, Pwd: "" }
 }
diff --git a/src/vms/vms.go b/src/vms/vms.go
index 03a001611e03afa9a38fba360c423acb894cba0f..f16b70b36997aabc079dd037c38d444ac8cd8e31 100644
--- a/src/vms/vms.go
+++ b/src/vms/vms.go
@@ -1,31 +1,31 @@
 package vms
 
 import (
-	"os"
-	"sort"
-	"sync"
-	"math"
-	"errors"
-	"path/filepath"
-	"nexus-server/exec"
-	"nexus-server/caps"
-	"nexus-server/paths"
-	"nexus-server/utils"
-	"nexus-server/logger"
-	"nexus-server/consts"
-	"github.com/google/uuid"
+    "os"
+    "sort"
+    "sync"
+    "math"
+    "errors"
+    "path/filepath"
+    "nexus-server/exec"
+    "nexus-server/caps"
+    "nexus-server/paths"
+    "nexus-server/utils"
+    "nexus-server/logger"
+    "nexus-server/consts"
+    "github.com/google/uuid"
 )
 
 type (
-	VMKeeperFn func(vm VM) bool
-
-	VMs struct {
-		m map[string]VM
-		dir string             // Base directory where VMs are stored
-		rwlock *sync.RWMutex   // RWlock to ensure the coherency of the map (m) of VMs
-		usedPorts [65536]bool  // Indicates which ports are used by the VMs
-		usedRAM int            // Used RAM by running VMs (in MB)
-	}
+    VMKeeperFn func(vm VM) bool
+
+    VMs struct {
+        m map[string]VM
+        dir string             // Base directory where VMs are stored
+        rwlock *sync.RWMutex   // RWlock to ensure the coherency of the map (m) of VMs
+        usedPorts [65536]bool  // Indicates which ports are used by the VMs
+        usedRAM int            // Used RAM by running VMs (in MB)
+    }
 )
 
 var log = logger.GetInstance()
@@ -34,441 +34,441 @@ var vms *VMs
 // Returns a VMs "singleton".
 // IMPORTANT: the InitVMs function must have been previously called!
 func GetVMsInstance() *VMs {
-	return vms
+    return vms
 }
 
 // Creates all VMs from their files on disk.
 // NOTE: path is the root directory where VMs reside.
 func InitVMs() error {
-	vmsDir := paths.GetInstance().VMsDir
-	vms = &VMs { m: make(map[string]VM), dir: vmsDir, rwlock: new(sync.RWMutex), usedRAM: 0 }
-
-	errMsg := "Failed reading VMs directory: "
-	dirs1, err := utils.GetSubDirs(vmsDir)
-	if err != nil {
-		return errors.New(errMsg+err.Error())
-	}
-
-	for d1 := range(dirs1) {
-		dirs2, err := utils.GetSubDirs(dirs1[d1])
-		if err != nil {
-			return errors.New(errMsg+err.Error())
-		}
-
-		for d2 := range(dirs2) {
-			dirs3, err := utils.GetSubDirs(dirs2[d2])
-			if err != nil {
-				return errors.New(errMsg+err.Error())
-			}
-
-			for i := range(dirs3) {
-				vmDir := dirs3[i]
-				filename := filepath.Join(vmDir, vmConfFile)
-				vm, err := newVMFromFile(filename)
-				if err != nil {
-					log.Warn("Skipping VM: failed reading \""+filename+"\" "+err.Error())
-					continue
-				}
-
-				filename = filepath.Join(vmDir, vmDiskFile)
-				f, err := os.OpenFile(filename, os.O_RDONLY, 0)
-				if err != nil {
-					log.Warn("Skipping VM: failed reading config file:"+err.Error())
-					continue
-				}
-				f.Close()
-
-				vms.m[vm.ID.String()] = *vm
-			}
-		}
-	}
-
-	return nil
+    vmsDir := paths.GetInstance().VMsDir
+    vms = &VMs { m: make(map[string]VM), dir: vmsDir, rwlock: new(sync.RWMutex), usedRAM: 0 }
+
+    errMsg := "Failed reading VMs directory: "
+    dirs1, err := utils.GetSubDirs(vmsDir)
+    if err != nil {
+        return errors.New(errMsg+err.Error())
+    }
+
+    for d1 := range(dirs1) {
+        dirs2, err := utils.GetSubDirs(dirs1[d1])
+        if err != nil {
+            return errors.New(errMsg+err.Error())
+        }
+
+        for d2 := range(dirs2) {
+            dirs3, err := utils.GetSubDirs(dirs2[d2])
+            if err != nil {
+                return errors.New(errMsg+err.Error())
+            }
+
+            for i := range(dirs3) {
+                vmDir := dirs3[i]
+                filename := filepath.Join(vmDir, vmConfFile)
+                vm, err := newVMFromFile(filename)
+                if err != nil {
+                    log.Warn("Skipping VM: failed reading \""+filename+"\" "+err.Error())
+                    continue
+                }
+
+                filename = filepath.Join(vmDir, vmDiskFile)
+                f, err := os.OpenFile(filename, os.O_RDONLY, 0)
+                if err != nil {
+                    log.Warn("Skipping VM: failed reading config file:"+err.Error())
+                    continue
+                }
+                f.Close()
+
+                vms.m[vm.ID.String()] = *vm
+            }
+        }
+    }
+
+    return nil
 }
 
 // Returns the list of serialized VMs for which VMKeeperFn returns true.
 func (vms *VMs)GetNetworkSerializedVMs(keepFn VMKeeperFn) []VMNetworkSerialized {
-	vms.rwlock.RLock()
-	list := []VMNetworkSerialized{}
-	for _, vm := range vms.m {
-		if keepFn(vm) {
-			list = append(list, vm.SerializeToNetwork())
-		}
-	}
-	vms.rwlock.RUnlock()
-	
-	// Sort VMs by names
-	sort.Slice(list, func(i, j int) bool {
+    vms.rwlock.RLock()
+    list := []VMNetworkSerialized{}
+    for _, vm := range vms.m {
+        if keepFn(vm) {
+            list = append(list, vm.SerializeToNetwork())
+        }
+    }
+    vms.rwlock.RUnlock()
+
+    // Sort VMs by names
+    sort.Slice(list, func(i, j int) bool {
         return list[i].Name < list[j].Name
     })
-	return list
+    return list
 }
 
 // Returns a VM by its ID.
 func (vms *VMs)GetVM(vmID uuid.UUID) (VM, error) {
-	vms.rwlock.RLock()
-	defer vms.rwlock.RUnlock()
-	return vms.getVMUnsafe(vmID)
+    vms.rwlock.RLock()
+    defer vms.rwlock.RUnlock()
+    return vms.getVMUnsafe(vmID)
 }
 
 func (vms *VMs)getVMUnsafe(vmID uuid.UUID) (VM, error) {
-	vm, exists := vms.m[vmID.String()]
-	if !exists {
-		return dummyVM, errors.New("VM not found")
-	}
-	return vm, nil
+    vm, exists := vms.m[vmID.String()]
+    if !exists {
+        return dummyVM, errors.New("VM not found")
+    }
+    return vm, nil
 }
 
 // Deletes a VM by its ID and deletes its files.
 func (vms *VMs)DeleteVM(vmID uuid.UUID) error {
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
-
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return err
-	}
-
-	// Deletes the VM's files (and directories).
-	vm.mutex.Lock()
-	if err := vm.delete(); err != nil {
-		vm.mutex.Unlock()
-		return err
-	}
-	vm.mutex.Unlock()
-	// Removes the VM from the map.
-	delete(vms.m, vmID.String())
-	return nil
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return err
+    }
+
+    // Deletes the VM's files (and directories).
+    vm.mutex.Lock()
+    if err := vm.delete(); err != nil {
+        vm.mutex.Unlock()
+        return err
+    }
+    vm.mutex.Unlock()
+    // Removes the VM from the map.
+    delete(vms.m, vmID.String())
+    return nil
 }
 
 // Adds a VM and writes its files.
 func (vms *VMs)AddVM(vm *VM) error {
-	vm.mutex.Lock()
-	// First, writes VM files since it can fail.
-	err := vm.writeFiles()
-	if err != nil {
-		vm.mutex.Unlock()
-		return err
-	}
-	vm.mutex.Unlock()
-
-	// Adds VM to the map of VMs.
-	vms.rwlock.Lock()
-	key := vm.ID.String()
-	vms.m[key] = *vm
-	vms.rwlock.Unlock()
-
-	return nil
+    vm.mutex.Lock()
+    // First, writes VM files since it can fail.
+    err := vm.writeFiles()
+    if err != nil {
+        vm.mutex.Unlock()
+        return err
+    }
+    vm.mutex.Unlock()
+
+    // Adds VM to the map of VMs.
+    vms.rwlock.Lock()
+    key := vm.ID.String()
+    vms.m[key] = *vm
+    vms.rwlock.Unlock()
+
+    return nil
 }
 
 // Starts a VM by its ID.
 // Returns the port on which the VM is running and the access password.
 func (vms *VMs)StartVM(vmID uuid.UUID) (int, string, error) {
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
-
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return 0, "", err
-	}
-
-	totalRAM, availRAM, err := utils.GetRAM()
-	if err != nil {
-		return -1, "", errors.New("Failed obtaining memory info: "+err.Error())
-	}
-
-	// We estimate that KVM allows for ~30% RAM saving (due to page sharing across VMs).
-	estimatedVmRAM := int(math.Round(float64(vm.Ram)*(1.-consts.KsmRamSaving)))
-
-	vms.usedRAM += estimatedVmRAM
-
-	// Checks that at least 15% of the available RAM is left after the VM has started,
-	// otherwise, refuses to run it in order to avoid RAM saturation.
-	if availRAM - vms.usedRAM <= int(math.Round(float64(totalRAM)*(1.-consts.RamUsageLimit))) {
-		vms.usedRAM -= estimatedVmRAM
-		return -1, "", errors.New("Insufficient free RAM to start VM")
-	}
-
-	// Locates a free port randomly chosen between VMSpiceMinPort and VMSpiceMaxPort (inclusive).
-	var port int
-	for {
-		port = utils.Rand(consts.VMSpiceMinPort, consts.VMSpiceMaxPort)
-		if !vms.usedPorts[port] {
-			if utils.IsPortAvailable(port) {
-				vms.usedPorts[port] = true
-				break
-			}
-		}
-	}
-
-	// This callback is called once the VM started with vm.start terminates.
-	endofExecFn := func (vm *VM) {
-		vm.mutex.Lock()
-		vm.removeSecretFile()
-		vm.resetStates()
-		vm.mutex.Unlock()
-		vms.rwlock.Lock()
-		vms.usedPorts[vm.Run.Port] = false
-		vms.usedRAM -= estimatedVmRAM
-		vms.updateVMMap(vm)
-		vms.rwlock.Unlock()
-	}
-
-	vm.mutex.Lock()
-	pwd, err := vm.start(port, endofExecFn)
-	vms.updateVMMap(&vm)
-	vm.mutex.Unlock()
-
-	return port, pwd, err
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return 0, "", err
+    }
+
+    totalRAM, availRAM, err := utils.GetRAM()
+    if err != nil {
+        return -1, "", errors.New("Failed obtaining memory info: "+err.Error())
+    }
+
+    // We estimate that KVM allows for ~30% RAM saving (due to page sharing across VMs).
+    estimatedVmRAM := int(math.Round(float64(vm.Ram)*(1.-consts.KsmRamSaving)))
+
+    vms.usedRAM += estimatedVmRAM
+
+    // Checks that at least 15% of the available RAM is left after the VM has started,
+    // otherwise, refuses to run it in order to avoid RAM saturation.
+    if availRAM - vms.usedRAM <= int(math.Round(float64(totalRAM)*(1.-consts.RamUsageLimit))) {
+        vms.usedRAM -= estimatedVmRAM
+        return -1, "", errors.New("Insufficient free RAM to start VM")
+    }
+
+    // Locates a free port randomly chosen between VMSpiceMinPort and VMSpiceMaxPort (inclusive).
+    var port int
+    for {
+        port = utils.Rand(consts.VMSpiceMinPort, consts.VMSpiceMaxPort)
+        if !vms.usedPorts[port] {
+            if utils.IsPortAvailable(port) {
+                vms.usedPorts[port] = true
+                break
+            }
+        }
+    }
+
+    // This callback is called once the VM started with vm.start terminates.
+    endofExecFn := func (vm *VM) {
+        vm.mutex.Lock()
+        vm.removeSecretFile()
+        vm.resetStates()
+        vm.mutex.Unlock()
+        vms.rwlock.Lock()
+        vms.usedPorts[vm.Run.Port] = false
+        vms.usedRAM -= estimatedVmRAM
+        vms.updateVMMap(vm)
+        vms.rwlock.Unlock()
+    }
+
+    vm.mutex.Lock()
+    pwd, err := vm.start(port, endofExecFn)
+    vms.updateVMMap(&vm)
+    vm.mutex.Unlock()
+
+    return port, pwd, err
 }
 
 // Kills a VM by its ID.
 func (vms *VMs)KillVM(vmID uuid.UUID) error {
-	vms.rwlock.RLock()
-	defer vms.rwlock.RUnlock()
-
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return err
-	}
-
-	vm.mutex.Lock()
-	err = vm.kill()
-	vm.mutex.Unlock()
-	return err
+    vms.rwlock.RLock()
+    defer vms.rwlock.RUnlock()
+
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return err
+    }
+
+    vm.mutex.Lock()
+    err = vm.kill()
+    vm.mutex.Unlock()
+    return err
 }
 
 // Gracefully stops a VM by its ID.
 func (vms *VMs)ShutdownVM(vmID uuid.UUID) error {
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
-
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return err
-	}
-
-	vm.mutex.Lock()
-	err = vm.shutdown()
-	vm.mutex.Unlock()
-	return err
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return err
+    }
+
+    vm.mutex.Lock()
+    err = vm.shutdown()
+    vm.mutex.Unlock()
+    return err
 }
 
 // Reboots a VM by its ID.
 func (vms *VMs)RebootVM(vmID uuid.UUID) error {
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
-
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return err
-	}
-
-	vm.mutex.Lock()
-	err = vm.reboot()
-	vm.mutex.Unlock()
-	return err
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return err
+    }
+
+    vm.mutex.Lock()
+    err = vm.reboot()
+    vm.mutex.Unlock()
+    return err
 }
 
 // Returns true if the given template is used by a VM.
 func (vms *VMs)IsTemplateUsed(templateID string) bool {
-	vms.rwlock.RLock()
-	defer vms.rwlock.RUnlock()
-
-	for _, vm := range vms.m {
-		if vm.TemplateID.String() == templateID {
-			return true
-		}
-	}
-	return false
+    vms.rwlock.RLock()
+    defer vms.rwlock.RUnlock()
+
+    for _, vm := range vms.m {
+        if vm.TemplateID.String() == templateID {
+            return true
+        }
+    }
+    return false
 }
 
 // Edit a VM' specs: name, cpus, ram, nic
 func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic NicType) error {
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return err
-	}
-
-	// Only updates fields that have changed.
-	if name != "" {
-		vm.Name = name
-	}
-	if cpus > 0 {
-		vm.Cpus = cpus
-	}
-	if ram > 0 {
-		vm.Ram = ram
-	}
-	if nic != "" {
-		vm.Nic = nic
-	}
-
-	if err = vm.validate(); err != nil {
-		return err
-	}
-
-	vm.mutex.Lock()
-	defer vm.mutex.Unlock()
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
-
-	if err = vms.updateVM(&vm); err != nil {
-		return err
-	}
-
-	return nil
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return err
+    }
+
+    // Only updates fields that have changed.
+    if name != "" {
+        vm.Name = name
+    }
+    if cpus > 0 {
+        vm.Cpus = cpus
+    }
+    if ram > 0 {
+        vm.Ram = ram
+    }
+    if nic != "" {
+        vm.Nic = nic
+    }
+
+    if err = vm.validate(); err != nil {
+        return err
+    }
+
+    vm.mutex.Lock()
+    defer vm.mutex.Unlock()
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
+    if err = vms.updateVM(&vm); err != nil {
+        return err
+    }
+
+    return nil
 }
 
 // Set a VM's Access for a given user (email).
 // loggedUserEmail is the email of the currently logged user
 // userMail is the email of the user for which to modify the access
 func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, newAccess caps.Capabilities) error {
-	if err := caps.ValidateVMAccessCaps(newAccess); err != nil {
-		return err
-	}
-
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
-
-	// Retrieves the VM for which the access caps must be changed.
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return err
-	}
-
-	vm.mutex.Lock()
-	defer vm.mutex.Unlock()
-
-	// First, check that the logged user is the VM's owner.
-	if !vm.IsOwner(loggedUserEmail) {
-		// Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
-		userCaps := vm.Access[loggedUserEmail]
-		_, exists := userCaps[caps.CAP_VM_SET_ACCESS]
-		if !exists {
-			return errors.New("Insufficient capability")
-		}
-	}
-
-	vm.Access[userEmail] = newAccess
-
-	if err = vms.updateVM(&vm); err != nil {
-		return err
-	}
-
-	return nil
+    if err := caps.ValidateVMAccessCaps(newAccess); err != nil {
+        return err
+    }
+
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
+    // Retrieves the VM for which the access caps must be changed.
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return err
+    }
+
+    vm.mutex.Lock()
+    defer vm.mutex.Unlock()
+
+    // First, check that the logged user is the VM's owner.
+    if !vm.IsOwner(loggedUserEmail) {
+        // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
+        userCaps := vm.Access[loggedUserEmail]
+        _, exists := userCaps[caps.CAP_VM_SET_ACCESS]
+        if !exists {
+            return errors.New("Insufficient capability")
+        }
+    }
+
+    vm.Access[userEmail] = newAccess
+
+    if err = vms.updateVM(&vm); err != nil {
+        return err
+    }
+
+    return nil
 }
 
 // Remove a VM's Access for a given user (email).
 // loggedUserEmail is the email of the currently logged user
 // userMail is the email of the user for which to remove the access
 func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string) error {
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
-
-	// Retrieves the VM for which the access caps must be changed.
-	vm, err := vms.getVMUnsafe(vmID)
-	if err != nil {
-		return err
-	}
-
-	vm.mutex.Lock()
-	defer vm.mutex.Unlock()
-
-	// First, check that the logged user is the VM's owner.
-	if !vm.IsOwner(loggedUserEmail) {
-		// Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
-		userCaps := vm.Access[loggedUserEmail]
-		_, exists := userCaps[caps.CAP_VM_SET_ACCESS]
-		if !exists {
-			return errors.New("Insufficient capability")
-		}
-	}
-
-	// Only removes the user from the Access map if it actually had an access.
-	if _, exists := vm.Access[userEmail]; exists {
-		delete(vm.Access, userEmail)
-	} else {
-		return errors.New("User "+userEmail+" has no VM access")
-	}
-
-	if err = vms.updateVM(&vm); err != nil {
-		return err
-	}
-
-	return nil
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
+    // Retrieves the VM for which the access caps must be changed.
+    vm, err := vms.getVMUnsafe(vmID)
+    if err != nil {
+        return err
+    }
+
+    vm.mutex.Lock()
+    defer vm.mutex.Unlock()
+
+    // First, check that the logged user is the VM's owner.
+    if !vm.IsOwner(loggedUserEmail) {
+        // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
+        userCaps := vm.Access[loggedUserEmail]
+        _, exists := userCaps[caps.CAP_VM_SET_ACCESS]
+        if !exists {
+            return errors.New("Insufficient capability")
+        }
+    }
+
+    // Only removes the user from the Access map if it actually had an access.
+    if _, exists := vm.Access[userEmail]; exists {
+        delete(vm.Access, userEmail)
+    } else {
+        return errors.New("User "+userEmail+" has no VM access")
+    }
+
+    if err = vms.updateVM(&vm); err != nil {
+        return err
+    }
+
+    return nil
 }
 
 // Exports a VM's directory and its subdirectories into a tar.gz archive on the host.
 func (vms *VMs)ExportVMFiles(vm *VM, vmDir, tarGzFile string) error {
-	vmDisk := vm.getDiskPath()
-	return exec.CopyFromVM(vmDisk, vmDir, tarGzFile)
+    vmDisk := vm.getDiskPath()
+    return exec.CopyFromVM(vmDisk, vmDir, tarGzFile)
 }
 
 // Imports files from a tar.gz archive into a VM's filesystem, in a specified directory.
 func (vms *VMs)ImportFilesToVM(vm *VM, tarGzFile, vmDir string) error {
-	// Marks the VM to copy from as being busy.
-	if err := vms.setDiskBusy(vm); err != nil {
-		return errors.New("Failed setting disk busy flag during VM files import: "+err.Error())
-	}
-	// Clears the VM from being busy.
-	defer vms.clearDiskBusy(vm)
-
-	vmDisk := vm.getDiskPath()
-	return exec.CopyToVM(vmDisk, tarGzFile, vmDir)
+    // Marks the VM to copy from as being busy.
+    if err := vms.setDiskBusy(vm); err != nil {
+        return errors.New("Failed setting disk busy flag during VM files import: "+err.Error())
+    }
+    // Clears the VM from being busy.
+    defer vms.clearDiskBusy(vm)
+
+    vmDisk := vm.getDiskPath()
+    return exec.CopyToVM(vmDisk, tarGzFile, vmDir)
 }
 
 // Marks a VM as "busy", meaning its disk file is being accessed for a possibly long time.
 func (vms *VMs)setDiskBusy(vm *VM) error {
-	vm.mutex.Lock()
-	defer vm.mutex.Unlock()
+    vm.mutex.Lock()
+    defer vm.mutex.Unlock()
 
-	if vm.IsRunning() {
-		return errors.New("Only a non-running VM can be set to busy")
-	}
+    if vm.IsRunning() {
+        return errors.New("Only a non-running VM can be set to busy")
+    }
 
-	vm.DiskBusy = true
+    vm.DiskBusy = true
 
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
 
-	vms.updateVMMap(vm)
+    vms.updateVMMap(vm)
 
-	return nil
+    return nil
 }
 
 func (vms *VMs)clearDiskBusy(vm *VM) error {
-	vm.mutex.Lock()
-	defer vm.mutex.Unlock()
+    vm.mutex.Lock()
+    defer vm.mutex.Unlock()
 
-	if vm.IsRunning() {
-		return errors.New("Only a non-running VM can have its busy flag cleared")
-	}
+    if vm.IsRunning() {
+        return errors.New("Only a non-running VM can have its busy flag cleared")
+    }
 
-	vm.DiskBusy = false
+    vm.DiskBusy = false
 
-	vms.rwlock.Lock()
-	defer vms.rwlock.Unlock()
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
 
-	vms.updateVMMap(vm)
+    vms.updateVMMap(vm)
 
-	return nil
+    return nil
 }
 
 // Updates a VM in the map of VMs and writes its updated config file.
 func (vms *VMs)updateVM(vm *VM) error {
-	err := vm.writeConfig()
-	if err != nil {
-		return err
-	}
+    err := vm.writeConfig()
+    if err != nil {
+        return err
+    }
 
-	vms.updateVMMap(vm)
-	return nil
+    vms.updateVMMap(vm)
+    return nil
 }
 
 // Updates a VM in the map of VMs.
 func (vms *VMs)updateVMMap(vm *VM) {
-	key := vm.ID.String()
-	delete(vms.m, key)
-	vms.m[key] = *vm
+    key := vm.ID.String()
+    delete(vms.m, key)
+    vms.m[key] = *vm
 }
diff --git a/tools/genpwd/src/genpwd.go b/tools/genpwd/src/genpwd.go
index 218e7b9c622313427596e0f36e5b842147b69346..041ec85550dea9c7d417a6b73b37df6ab515578a 100644
--- a/tools/genpwd/src/genpwd.go
+++ b/tools/genpwd/src/genpwd.go
@@ -1,32 +1,32 @@
 package main
 
 import (
-	"os"
-	"fmt"
-	"syscall"
-	"golang.org/x/term"
-	"golang.org/x/crypto/bcrypt"
+    "os"
+    "fmt"
+    "syscall"
+    "golang.org/x/term"
+    "golang.org/x/crypto/bcrypt"
 )
 
 func main() {
-	fmt.Printf("Enter password: ")
+    fmt.Printf("Enter password: ")
 
-	bytePwd, err := term.ReadPassword(int(syscall.Stdin))
+    bytePwd, err := term.ReadPassword(int(syscall.Stdin))
     if err != nil {
-		fmt.Println(err.Error())
+        fmt.Println(err.Error())
         os.Exit(1)
     }
-	pwd := string(bytePwd)
+    pwd := string(bytePwd)
 
-	hashedPwd, _ := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
-	stringPwd := string(hashedPwd)
+    hashedPwd, _ := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
+    stringPwd := string(hashedPwd)
 
-	fmt.Println("")
-	fmt.Println(stringPwd)
+    fmt.Println("")
+    fmt.Println(stringPwd)
 
-	// if err := bcrypt.CompareHashAndPassword(hashedPwd, []byte("pipo")); err != nil {
-	// 	fmt.Println("don't match!")
-	// } else {
-	// 	fmt.Println("OK")
-	// }
+    // if err := bcrypt.CompareHashAndPassword(hashedPwd, []byte("pipo")); err != nil {
+    //  fmt.Println("don't match!")
+    // } else {
+    //  fmt.Println("OK")
+    // }
 }