mirror of
https://github.com/Forceu/Gokapi.git
synced 2026-05-18 05:28:43 -05:00
Better error handling for permission errors or other file related errors #326
This commit is contained in:
@@ -5,12 +5,13 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/forceu/gokapi/cmd/cli-uploader/cliapi"
|
||||
"github.com/forceu/gokapi/cmd/cli-uploader/cliconstants"
|
||||
"github.com/forceu/gokapi/cmd/cli-uploader/cliflags"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type configFile struct {
|
||||
@@ -135,17 +136,16 @@ func save(url, apikey string, e2ekey []byte) error {
|
||||
// Verifies the existence of the configuration file and validates its integrity, terminating on errors.
|
||||
func Load() {
|
||||
configPath, _ := cliflags.GetConfigLocation()
|
||||
if !helper.FileExists(configPath) {
|
||||
exists, err := helper.FileExists(configPath)
|
||||
helper.Check(err)
|
||||
if !exists {
|
||||
fmt.Println("ERROR: No login information found")
|
||||
fmt.Println("Please run 'gokapi-cli login' to create a login")
|
||||
os.Exit(1)
|
||||
}
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR: Could not read login information")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
helper.Check(err)
|
||||
|
||||
var config configFile
|
||||
err = json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
@@ -160,7 +160,13 @@ func Load() {
|
||||
// It will return an error if the file exists but could not be deleted.
|
||||
func Delete() error {
|
||||
configPath, _ := cliflags.GetConfigLocation()
|
||||
if !helper.FileExists(configPath) {
|
||||
exists, err := helper.FileExists(configPath)
|
||||
if err != nil {
|
||||
fmt.Println("ERROR: Could not check if login information exists")
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
return os.Remove(configPath)
|
||||
|
||||
@@ -11,6 +11,10 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/forceu/gokapi/internal/configuration/cloudconfig"
|
||||
"github.com/forceu/gokapi/internal/configuration/configupgrade"
|
||||
"github.com/forceu/gokapi/internal/configuration/database"
|
||||
@@ -19,9 +23,6 @@ import (
|
||||
"github.com/forceu/gokapi/internal/logging"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
"github.com/forceu/gokapi/internal/storage/filesystem"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MinLengthPassword is the required length of admin password in characters
|
||||
@@ -38,7 +39,9 @@ var usesHttps bool
|
||||
// Exists returns true if configuration files are present
|
||||
func Exists() bool {
|
||||
configPath, _, _, _ := environment.GetConfigPaths()
|
||||
return helper.FileExists(configPath)
|
||||
exists, err := helper.FileExists(configPath)
|
||||
helper.Check(err)
|
||||
return exists
|
||||
}
|
||||
|
||||
// loadFromFile parses the given file and adds salts, if they are invalid
|
||||
|
||||
@@ -2,12 +2,13 @@ package cloudconfig
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/forceu/gokapi/internal/environment"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// CloudConfig contains all configuration values / credentials for cloud storage
|
||||
@@ -22,7 +23,9 @@ func Load() (CloudConfig, bool) {
|
||||
return loadFromEnv(&env), true
|
||||
}
|
||||
path := env.ConfigDir + "/cloudconfig.yml"
|
||||
if helper.FileExists(path) {
|
||||
exists, err := helper.FileExists(path)
|
||||
helper.Check(err)
|
||||
if exists {
|
||||
return loadFromFile(path)
|
||||
}
|
||||
return CloudConfig{}, false
|
||||
@@ -49,8 +52,10 @@ func Write(config CloudConfig) error {
|
||||
// Delete removes the cloud config file from the set config path
|
||||
func Delete() error {
|
||||
_, _, _, awsConfigPath := environment.GetConfigPaths()
|
||||
if helper.FileExists(awsConfigPath) {
|
||||
err := os.Remove(awsConfigPath)
|
||||
exists, err := helper.FileExists(awsConfigPath)
|
||||
helper.Check(err)
|
||||
if exists {
|
||||
err = os.Remove(awsConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ package database
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/forceu/gokapi/internal/configuration/database/dbabstraction"
|
||||
"github.com/forceu/gokapi/internal/configuration/database/dbcache"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var db dbabstraction.Database
|
||||
@@ -37,8 +38,14 @@ func ParseUrl(dbUrl string, mustExist bool) (models.DbConnection, error) {
|
||||
case "sqlite":
|
||||
result.Type = dbabstraction.TypeSqlite
|
||||
result.HostUrl = strings.TrimPrefix(dbUrl, "sqlite://")
|
||||
if mustExist && !helper.FileExists(result.HostUrl) {
|
||||
return models.DbConnection{}, fmt.Errorf("file %s does not exist\n", result.HostUrl)
|
||||
if mustExist {
|
||||
exist, errEx := helper.FileExists(result.HostUrl)
|
||||
if errEx != nil {
|
||||
return models.DbConnection{}, errEx
|
||||
}
|
||||
if !exist {
|
||||
return models.DbConnection{}, fmt.Errorf("file %s does not exist\n", result.HostUrl)
|
||||
}
|
||||
}
|
||||
case "redis":
|
||||
result.Type = dbabstraction.TypeRedis
|
||||
|
||||
@@ -4,10 +4,11 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
// Required for sqlite driver
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
@@ -82,7 +83,9 @@ func (p DatabaseProvider) init(dbConfig models.DbConnection) (DatabaseProvider,
|
||||
p.sqliteDb.SetMaxOpenConns(5)
|
||||
p.sqliteDb.SetMaxIdleConns(5)
|
||||
|
||||
if !helper.FileExists(dbConfig.HostUrl) {
|
||||
exists, err := helper.FileExists(dbConfig.HostUrl)
|
||||
helper.Check(err)
|
||||
if !exists {
|
||||
return p, p.createNewDatabase()
|
||||
}
|
||||
err = p.sqliteDb.Ping()
|
||||
|
||||
@@ -7,10 +7,11 @@ Simplified OS functions
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"golang.org/x/term"
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
// FolderExists returns true if a folder exists
|
||||
@@ -23,12 +24,15 @@ func FolderExists(folder string) bool {
|
||||
}
|
||||
|
||||
// FileExists returns true if a file exists
|
||||
func FileExists(filename string) bool {
|
||||
func FileExists(filename string) (bool, error) {
|
||||
info, err := os.Stat(filename)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
return !info.IsDir()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return !info.IsDir(), nil
|
||||
}
|
||||
|
||||
// CreateDir creates the data folder if it does not exist
|
||||
|
||||
@@ -2,9 +2,10 @@ package helper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/forceu/gokapi/internal/test"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/forceu/gokapi/internal/test"
|
||||
)
|
||||
|
||||
func TestIsInArray(t *testing.T) {
|
||||
@@ -15,16 +16,20 @@ func TestIsInArray(t *testing.T) {
|
||||
func TestFolderCreation(t *testing.T) {
|
||||
test.IsEqualBool(t, FolderExists("invalid"), false)
|
||||
test.FileDoesNotExist(t, "invalid/file")
|
||||
test.IsEqualBool(t, FileExists("invalid/file"), false)
|
||||
exists, err := FileExists("invalid/file")
|
||||
test.IsEqualBool(t, exists, false)
|
||||
test.IsNil(t, err)
|
||||
CreateDir("invalid")
|
||||
test.IsEqualBool(t, FolderExists("invalid"), true)
|
||||
err := os.WriteFile("invalid/file", []byte("test"), 0644)
|
||||
err = os.WriteFile("invalid/file", []byte("test"), 0644)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
test.FileExists(t, "invalid/file")
|
||||
test.IsEqualBool(t, FileExists("invalid/file"), true)
|
||||
os.RemoveAll("invalid")
|
||||
exists, err = FileExists("invalid/file")
|
||||
test.IsNil(t, err)
|
||||
test.IsEqualBool(t, exists, true)
|
||||
_ = os.RemoveAll("invalid")
|
||||
}
|
||||
|
||||
func TestReadLine(t *testing.T) {
|
||||
|
||||
@@ -3,15 +3,16 @@ package logging
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/forceu/gokapi/internal/environment"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/forceu/gokapi/internal/environment"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
)
|
||||
|
||||
var logPath = "config/log.txt"
|
||||
@@ -35,7 +36,9 @@ func Init(filePath string) {
|
||||
|
||||
// GetAll returns all log entries as a single string and if the log file exists
|
||||
func GetAll() (string, bool) {
|
||||
if helper.FileExists(logPath) {
|
||||
exists, err := helper.FileExists(logPath)
|
||||
helper.Check(err)
|
||||
if exists {
|
||||
content, err := os.ReadFile(logPath)
|
||||
helper.Check(err)
|
||||
return string(content), true
|
||||
|
||||
@@ -10,6 +10,16 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/forceu/gokapi/internal/configuration"
|
||||
"github.com/forceu/gokapi/internal/configuration/database"
|
||||
"github.com/forceu/gokapi/internal/encryption"
|
||||
@@ -25,15 +35,6 @@ import (
|
||||
"github.com/forceu/gokapi/internal/webserver/headers"
|
||||
"github.com/forceu/gokapi/internal/webserver/sse"
|
||||
"github.com/jinzhu/copier"
|
||||
"io"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErrorFileTooLarge is an error that is called when a file larger than the set maximum is uploaded
|
||||
@@ -668,7 +669,9 @@ func FileExists(file models.File, dataDir string) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
return helper.FileExists(dataDir + "/" + file.SHA1)
|
||||
exists, err := helper.FileExists(dataDir + "/" + file.SHA1)
|
||||
helper.Check(err)
|
||||
return exists
|
||||
}
|
||||
|
||||
// CleanUp removes expired files from the config and from the filesystem if they are not referenced by other files anymore
|
||||
|
||||
@@ -2,8 +2,6 @@ package chunking
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/forceu/gokapi/internal/configuration"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
@@ -12,6 +10,9 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/forceu/gokapi/internal/configuration"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
)
|
||||
|
||||
// ChunkInfo contains info about the current chunk
|
||||
@@ -173,7 +174,9 @@ func GetFileByChunkId(id string) (*os.File, error) {
|
||||
|
||||
// FileExists returns true if a file exists for the given chunk ID
|
||||
func FileExists(id string) bool {
|
||||
return helper.FileExists(getChunkFilePath(id))
|
||||
exists, err := helper.FileExists(getChunkFilePath(id))
|
||||
helper.Check(err)
|
||||
return exists
|
||||
}
|
||||
|
||||
// NewChunk allocates the space for the new file and writes the chunk
|
||||
|
||||
@@ -2,11 +2,12 @@ package localstorage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"github.com/forceu/gokapi/internal/models"
|
||||
fileInterfaces "github.com/forceu/gokapi/internal/storage/filesystem/interfaces"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetDriver returns a driver for the local file system
|
||||
@@ -95,7 +96,9 @@ type localFile struct {
|
||||
|
||||
// Exists returns true if the file exists
|
||||
func (f *localFile) Exists() bool {
|
||||
return helper.FileExists(f.Directory + f.Filename)
|
||||
exists, err := helper.FileExists(f.Directory + f.Filename)
|
||||
helper.Check(err)
|
||||
return exists
|
||||
}
|
||||
|
||||
// GetName returns the name of the file
|
||||
|
||||
@@ -38,9 +38,15 @@ func loadCustomCssJsInfo(webserverDir fs.FS) {
|
||||
return
|
||||
}
|
||||
customStaticInfo.Version = strconv.Itoa(readCustomStaticVersion())
|
||||
customStaticInfo.UseCustomCss = helper.FileExists(pathCustomCss)
|
||||
customStaticInfo.UseCustomPublicJs = helper.FileExists(pathCustomPublicJs)
|
||||
customStaticInfo.UseCustomAdminJs = helper.FileExists(pathCustomAdminJs)
|
||||
exists, err := helper.FileExists(pathCustomCss)
|
||||
helper.Check(err)
|
||||
customStaticInfo.UseCustomCss = exists
|
||||
exists, err = helper.FileExists(pathCustomPublicJs)
|
||||
helper.Check(err)
|
||||
customStaticInfo.UseCustomPublicJs = exists
|
||||
exists, err = helper.FileExists(pathCustomAdminJs)
|
||||
helper.Check(err)
|
||||
customStaticInfo.UseCustomAdminJs = exists
|
||||
}
|
||||
|
||||
func addMuxForCustomContent(mux *http.ServeMux) {
|
||||
@@ -78,7 +84,9 @@ func serveCustomFile(filePath string, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func readCustomStaticVersion() int {
|
||||
if !helper.FileExists(pathCustomVersioning) {
|
||||
exists, err := helper.FileExists(pathCustomVersioning)
|
||||
helper.Check(err)
|
||||
if !exists {
|
||||
return 0
|
||||
}
|
||||
file, err := os.Open(pathCustomVersioning)
|
||||
|
||||
@@ -29,7 +29,9 @@ var faviconPng512x512 []byte
|
||||
|
||||
func Init(pathCustomIcon string, fsDefault fs.FS) {
|
||||
var imageContent []byte
|
||||
if helper.FileExists(pathCustomIcon) {
|
||||
exists, err := helper.FileExists(pathCustomIcon)
|
||||
helper.Check(err)
|
||||
if exists {
|
||||
content, err := os.ReadFile(pathCustomIcon)
|
||||
helper.Check(err)
|
||||
imageContent = content
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"github.com/forceu/gokapi/internal/environment"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
@@ -20,13 +18,20 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/forceu/gokapi/internal/environment"
|
||||
"github.com/forceu/gokapi/internal/helper"
|
||||
)
|
||||
|
||||
var configDir string
|
||||
|
||||
func isCertificatePresent() bool {
|
||||
certificate, key := GetCertificateLocations()
|
||||
return helper.FileExists(certificate) && helper.FileExists(key)
|
||||
existsCert, err := helper.FileExists(certificate)
|
||||
helper.Check(err)
|
||||
existsKey, err := helper.FileExists(key)
|
||||
helper.Check(err)
|
||||
return existsCert && existsKey
|
||||
}
|
||||
|
||||
// GetCertificateLocations returns the filepath of the public certificate and private key
|
||||
|
||||
Reference in New Issue
Block a user