add version and translate all pages
This commit is contained in:
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/vaultdrop/backend/config"
|
||||
@@ -14,6 +15,8 @@ import (
|
||||
"github.com/vaultdrop/backend/service"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
|
||||
func newRouter() *gin.Engine {
|
||||
r := gin.Default()
|
||||
handlers.RegisterRoutes(r)
|
||||
@@ -21,8 +24,12 @@ func newRouter() *gin.Engine {
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) > 1 && os.Args[1] == "--version" {
|
||||
fmt.Printf("vaultdrop-server %s\n", version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
err, cfg := config.LoadApplicationConfig()
|
||||
cfg, err := config.LoadApplicationConfig()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
|
||||
@@ -9,14 +9,14 @@ import (
|
||||
|
||||
func TestUserCreation(t *testing.T) {
|
||||
|
||||
err, userAntoine := models.NewUser("antoine")
|
||||
userAntoine, err := models.NewUser("antoine")
|
||||
if err != nil {
|
||||
t.Errorf(`Error creating antoine user %v`, err)
|
||||
t.Fatalf("creating antoine user: %v", err)
|
||||
}
|
||||
|
||||
err, userBob := models.NewUser("bob")
|
||||
userBob, err := models.NewUser("bob")
|
||||
if err != nil {
|
||||
t.Errorf(`Error creating bob user %v`, err)
|
||||
t.Fatalf("creating bob user: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(userAntoine, userBob)
|
||||
@@ -25,16 +25,16 @@ func TestUserCreation(t *testing.T) {
|
||||
|
||||
func TestCreateDocument(t *testing.T) {
|
||||
|
||||
err, document := models.NewDocument("paper.pdf", models.FILE, 1)
|
||||
document, err := models.NewDocument("paper.pdf", models.FILE, 1)
|
||||
if err != nil {
|
||||
t.Errorf(`Error creating document %v`, err)
|
||||
t.Fatalf("creating document: %v", err)
|
||||
}
|
||||
|
||||
err, directory := models.NewDocument("bob", models.DIRECTORY, 1)
|
||||
directory, err := models.NewDocument("bob", models.DIRECTORY, 1)
|
||||
if err != nil {
|
||||
t.Errorf(`Error creating bob directory %v`, err)
|
||||
t.Fatalf("creating bob directory: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(document, directory)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,22 +18,22 @@ type ApplicationConfig struct {
|
||||
AdminPassword string
|
||||
}
|
||||
|
||||
func LoadApplicationConfig() (error, *ApplicationConfig) {
|
||||
func LoadApplicationConfig() (*ApplicationConfig, error) {
|
||||
|
||||
// .env optionnel — les défauts suffisent pour le dev local.
|
||||
_ = godotenv.Load()
|
||||
|
||||
port, err := getInt("PORT", 8080)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maxSize, err := getInt("MAX_FILE_SIZE_MB", 50)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, &ApplicationConfig{
|
||||
return &ApplicationConfig{
|
||||
Port: port,
|
||||
DatabaseURL: get("DATABASE_URL", "postgres://vaultdrop:vaultdrop@localhost:5432/vaultdrop_dev?sslmode=disable"),
|
||||
UploadDir: get("UPLOAD_DIR", "./uploads"),
|
||||
@@ -42,7 +42,7 @@ func LoadApplicationConfig() (error, *ApplicationConfig) {
|
||||
AuthSecret: get("AUTH_SECRET", "dev-secret-change-me"),
|
||||
AdminUsername: get("ADMIN_USERNAME", ""),
|
||||
AdminPassword: get("ADMIN_PASSWORD", ""),
|
||||
}
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func clearEnv(t *testing.T) {
|
||||
func TestLoadApplicationDefaults(t *testing.T) {
|
||||
clearEnv(t)
|
||||
|
||||
err, cfg := LoadApplicationConfig()
|
||||
cfg, err := LoadApplicationConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("LoadApplicationConfig: %v", err)
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func TestLoadApplicationEnvOverrides(t *testing.T) {
|
||||
t.Setenv("ADMIN_USERNAME", "root")
|
||||
t.Setenv("ADMIN_PASSWORD", "toor")
|
||||
|
||||
err, cfg := LoadApplicationConfig()
|
||||
cfg, err := LoadApplicationConfig()
|
||||
if err != nil {
|
||||
t.Fatalf("LoadApplicationConfig: %v", err)
|
||||
}
|
||||
@@ -71,13 +71,13 @@ func TestLoadApplicationRejectsInvalidInt(t *testing.T) {
|
||||
clearEnv(t)
|
||||
|
||||
t.Setenv("PORT", "not-a-number")
|
||||
if err, _ := LoadApplicationConfig(); err == nil {
|
||||
if _, err := LoadApplicationConfig(); err == nil {
|
||||
t.Error("PORT invalide : attendu une erreur")
|
||||
}
|
||||
|
||||
clearEnv(t)
|
||||
t.Setenv("MAX_FILE_SIZE_MB", "99999999999999999999999")
|
||||
if err, _ := LoadApplicationConfig(); err == nil {
|
||||
if _, err := LoadApplicationConfig(); err == nil {
|
||||
t.Error("MAX_FILE_SIZE_MB invalide : attendu une erreur")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ func TestResolveUser(t *testing.T) {
|
||||
t.Errorf("resolve: %+v", env.Data)
|
||||
}
|
||||
// Jamais email ni is_admin
|
||||
if len(rec.Body.Bytes()) < 0 || strings.Contains(rec.Body.String(), "is_admin") || strings.Contains(rec.Body.String(), "email") {
|
||||
if len(rec.Body.Bytes()) == 0 || strings.Contains(rec.Body.String(), "is_admin") || strings.Contains(rec.Body.String(), "email") {
|
||||
t.Error("resolve ne doit pas exposer email/is_admin")
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
@@ -47,10 +46,3 @@ func RegisterRoutes(r *gin.Engine) {
|
||||
api.Error(c, http.StatusNotFound, "NOT_FOUND", "route not found")
|
||||
})
|
||||
}
|
||||
|
||||
// userID lit la clé de scoping posée par RequireAuth. Un empty string est
|
||||
// impossible en conditions normales (le middleware l'a validé) ; garde-fou
|
||||
// pour un appel direct dans les tests.
|
||||
func userID(c *gin.Context) string {
|
||||
return strings.TrimSpace(c.GetString(UserIDKey))
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func writeError(c *gin.Context, err error) {
|
||||
api.Error(c, 404, "GRANTEE_NOT_FOUND", "the specified user does not exist")
|
||||
case errors.Is(err, repository.ErrNameConflict):
|
||||
api.Error(c, 409, "NAME_CONFLICT", "a resource with this name already exists here")
|
||||
case errors.Is(err, service.FileTooLargeError):
|
||||
case errors.Is(err, service.ErrFileTooLarge):
|
||||
api.Error(c, 413, "FILE_TOO_LARGE", "file exceeds the maximum allowed size")
|
||||
default:
|
||||
api.Error(c, 500, "INTERNAL", err.Error())
|
||||
|
||||
@@ -8,19 +8,19 @@ type Client interface {
|
||||
GetClientVersion() int
|
||||
}
|
||||
|
||||
func NewClient(clientVersion int) (error, Client) {
|
||||
func NewClient(clientVersion int) (Client, error) {
|
||||
|
||||
isCompatible := ServerClientIsCompatibleWithClient(clientVersion)
|
||||
|
||||
if !isCompatible {
|
||||
return fmt.Errorf("You client version %d is not compatible with the server verison %d", clientVersion, SERVER_VERSION), nil
|
||||
return nil, fmt.Errorf("client version %d is not compatible with the server version %d", clientVersion, SERVER_VERSION)
|
||||
}
|
||||
|
||||
client := ClientVerisonOne{
|
||||
Version: clientVersion,
|
||||
}
|
||||
|
||||
return nil, &client
|
||||
return &client, nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type Document struct {
|
||||
@@ -37,19 +37,19 @@ func IsDirectory(documentType int) bool {
|
||||
return DIRECTORY == documentType
|
||||
}
|
||||
|
||||
func NewDocument(documentName string, documentType int, documentVersion int) (error, *Document) {
|
||||
func NewDocument(documentName string, documentType int, documentVersion int) (*Document, error) {
|
||||
|
||||
documentTypeIsValid := IsDocumentTypeValid(documentType)
|
||||
|
||||
if !documentTypeIsValid {
|
||||
return fmt.Errorf(ERROR_DOCUMENT_TYPE), nil
|
||||
return nil, errors.New(ERROR_DOCUMENT_TYPE)
|
||||
}
|
||||
|
||||
return nil, &Document{
|
||||
return &Document{
|
||||
Name: &documentName,
|
||||
Type: documentType,
|
||||
Version: documentVersion,
|
||||
}
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ type User struct {
|
||||
Username string
|
||||
}
|
||||
|
||||
func NewUser(username string) (error, *User) {
|
||||
return nil, &User{
|
||||
func NewUser(username string) (*User, error) {
|
||||
return &User{
|
||||
Username: username,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package service
|
||||
|
||||
import "github.com/vaultdrop/backend/models"
|
||||
|
||||
func (s *Services) CreateFolder(folderName string, destination *models.Document) (error, *models.Document) {
|
||||
func (s *Services) CreateFolder(folderName string, destination *models.Document) (*models.Document, error) {
|
||||
|
||||
err, directory := models.NewDocument(folderName, models.DIRECTORY, 1)
|
||||
directory, err := models.NewDocument(folderName, models.DIRECTORY, 1)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, directory
|
||||
return directory, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/vaultdrop/backend/models"
|
||||
@@ -9,19 +10,19 @@ import (
|
||||
func (s *Services) MoveDocumentIntoDocument(from *models.Document, to *models.Document) error {
|
||||
|
||||
if from.UUID == nil {
|
||||
return fmt.Errorf(models.ERROR_DOCUMENT_NOT_PERCISTED)
|
||||
return errors.New(models.ERROR_DOCUMENT_NOT_PERCISTED)
|
||||
}
|
||||
|
||||
if to.Type != models.DIRECTORY {
|
||||
return fmt.Errorf("The destination document must be a directory")
|
||||
return errors.New("the destination document must be a directory")
|
||||
}
|
||||
|
||||
if canEdit, _ := UserCanEditDocument(s.ConnectedUser, from); canEdit == false {
|
||||
return fmt.Errorf("You can not edit this folder")
|
||||
if canEdit, _ := UserCanEditDocument(s.ConnectedUser, from); !canEdit {
|
||||
return errors.New("you cannot edit this folder")
|
||||
}
|
||||
|
||||
if canEdit, _ := UserCanEditDocument(s.ConnectedUser, to); canEdit == false {
|
||||
return fmt.Errorf("You can not edit this folder")
|
||||
if canEdit, _ := UserCanEditDocument(s.ConnectedUser, to); !canEdit {
|
||||
return errors.New("you cannot edit this folder")
|
||||
}
|
||||
|
||||
// Check if document exist and move the document into document if is directory
|
||||
|
||||
@@ -8,23 +8,27 @@ import (
|
||||
|
||||
func TestMoveDocument(t *testing.T) {
|
||||
|
||||
err, userAntoine := models.NewUser("antoine")
|
||||
userAntoine, err := models.NewUser("antoine")
|
||||
if err != nil {
|
||||
t.Errorf(`Error creating antoine user %v`, err)
|
||||
t.Fatalf("creating antoine user: %v", err)
|
||||
}
|
||||
|
||||
fakeUUID := "dsqdsq"
|
||||
err, document := models.NewDocument("test.pdf", models.FILE, 1)
|
||||
document, err := models.NewDocument("test.pdf", models.FILE, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("creating document: %v", err)
|
||||
}
|
||||
document.UUID = &fakeUUID
|
||||
|
||||
err, folder := models.NewDocument("orga", models.DIRECTORY, 1)
|
||||
folder, err := models.NewDocument("orga", models.DIRECTORY, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("creating folder: %v", err)
|
||||
}
|
||||
folder.UUID = &fakeUUID
|
||||
|
||||
service := New(userAntoine)
|
||||
|
||||
err = service.MoveDocumentIntoDocument(document, folder)
|
||||
|
||||
if err != nil {
|
||||
if err := service.MoveDocumentIntoDocument(document, folder); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -32,14 +36,20 @@ func TestMoveDocument(t *testing.T) {
|
||||
|
||||
func TestMoveDocumentToAFile(t *testing.T) {
|
||||
|
||||
err, userAntoine := models.NewUser("antoine")
|
||||
userAntoine, err := models.NewUser("antoine")
|
||||
if err != nil {
|
||||
t.Errorf(`Error creating antoine user %v`, err)
|
||||
t.Fatalf("creating antoine user: %v", err)
|
||||
}
|
||||
|
||||
err, document := models.NewDocument("test.pdf", models.FILE, 1)
|
||||
document, err := models.NewDocument("test.pdf", models.FILE, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("creating document: %v", err)
|
||||
}
|
||||
|
||||
err, notAFolder := models.NewDocument("orga", models.FILE, 1)
|
||||
notAFolder, err := models.NewDocument("orga", models.FILE, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("creating file: %v", err)
|
||||
}
|
||||
|
||||
service := New(userAntoine)
|
||||
|
||||
@@ -49,4 +59,4 @@ func TestMoveDocumentToAFile(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"github.com/vaultdrop/backend/repository"
|
||||
)
|
||||
|
||||
// FileTooLargeError signals an upload above MaxFileSize.
|
||||
var FileTooLargeError = errors.New("file too large")
|
||||
// ErrFileTooLarge signals an upload above MaxFileSize.
|
||||
var ErrFileTooLarge = errors.New("file too large")
|
||||
|
||||
// FileDTO serializes exactly as mobile/api/types.ts FileDto.
|
||||
type FileDTO struct {
|
||||
@@ -106,7 +106,7 @@ func (s *Resources) SearchFiles(ownerID, q string, page, pageSize int) ([]FileDT
|
||||
// if metadata persistence fails (e.g. name conflict).
|
||||
func (s *Resources) Upload(ownerID string, file *multipart.FileHeader, folderID string) (FileDTO, error) {
|
||||
if file.Size > s.MaxFileSize {
|
||||
return FileDTO{}, FileTooLargeError
|
||||
return FileDTO{}, ErrFileTooLarge
|
||||
}
|
||||
|
||||
id := repository.NewID()
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func (s *Services) UploadDocument(file *string, destination *models.Document) error {
|
||||
|
||||
if canEdit, _ := UserCanEditDocument(s.ConnectedUser, destination); !canEdit {
|
||||
return fmt.Errorf("Can not edit")
|
||||
return fmt.Errorf("cannot edit document")
|
||||
}
|
||||
|
||||
models.NewDocument("test", models.FILE, 1)
|
||||
|
||||
Reference in New Issue
Block a user