Files
Gokapi/Configuration.go

198 lines
4.4 KiB
Go

package main
import (
"bufio"
"encoding/json"
"fmt"
"golang.org/x/crypto/ssh/terminal"
"log"
"os"
"strings"
)
const configDir = "config"
const configFile = "config.json"
const configPath = configDir + "/" + configFile
var globalConfig Configuration
type Configuration struct {
Port string `json:"Port"`
AdminName string `json:"AdminName"`
AdminPassword string `json:"AdminPassword"`
ServerUrl string `json:"ServerUrl"`
DefaultDownloads int `json:"DefaultDownloads"`
DefaultExpiry int `json:"DefaultExpiry"`
RedirectUrl string `json:"RedirectUrl"`
Sessions map[string]Session `json:"Sessions"`
Files map[string]FileList `json:"Files"`
}
func (f *FileList) toJsonResult() string {
result := Result{
Result: "OK",
Url: globalConfig.ServerUrl + "d?id=",
FileInfo: f,
}
bytes, err := json.Marshal(result)
if err != nil {
fmt.Println(err)
return "{\"Result\":\"error\",\"ErrorMessage\":\"" + err.Error() + "\"}"
}
return string(bytes)
}
func loadConfig() {
createConfigDir()
if !fileExists(configPath) {
generateDefaultConfig()
}
file, err := os.Open(configPath)
if err != nil {
log.Fatal(err)
}
defer file.Close()
decoder := json.NewDecoder(file)
globalConfig = Configuration{}
err = decoder.Decode(&globalConfig)
if err != nil {
log.Fatal(err)
}
}
func generateDefaultConfig() {
fmt.Println("First start, creating new admin account")
username := askForUsername()
password := askForPassword()
url := askForUrl()
redirect := askForRedirect()
localOnly := askForLocalOnly()
port := "127.0.0.1:53842"
if !localOnly {
port = "0.0.0.0:53842"
}
globalConfig = Configuration{
Port: port,
AdminName: username,
AdminPassword: hashPassword(password),
ServerUrl: url,
DefaultDownloads: 1,
DefaultExpiry: 14,
RedirectUrl: redirect,
Files: make(map[string]FileList),
Sessions: make(map[string]Session),
}
saveConfig()
}
func saveConfig() {
file, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
fmt.Println("Error reading configuration:", err)
os.Exit(1)
}
defer file.Close()
encoder := json.NewEncoder(file)
err = encoder.Encode(&globalConfig)
if err != nil {
fmt.Println("Error writing configuration:", err)
os.Exit(1)
}
}
func askForUsername() string {
fmt.Print("Username: ")
username := readLine()
if len(username) >= 4 {
return username
}
fmt.Println("Username needs to be at least 4 characters long")
return askForUsername()
}
func askForLocalOnly() bool {
if isDocker() {
return false
}
fmt.Print("Bind port to localhost only? [Y/n]: ")
input := strings.ToLower(readLine())
return input != "n"
}
func askForPassword() string {
fmt.Print("Password: ")
password1, err := terminal.ReadPassword(0)
check(err)
if len(password1) < 6 {
fmt.Println("\nPassword needs to be at least 6 characters long")
return askForPassword()
}
fmt.Print("\nPassword (repeat): ")
password2, err := terminal.ReadPassword(0)
check(err)
if string(password1) != string(password2) {
fmt.Println("\nPasswords dont match")
return askForPassword()
}
fmt.Println()
return string(password1)
}
func askForUrl() string {
fmt.Print("Server URL [eg. https://gokapi.url/]: ")
url := readLine()
if !isValidUrl(url) {
return askForUrl()
}
if !strings.HasSuffix(url, "/") {
url = url + "/"
}
return url
}
func askForRedirect() string {
fmt.Print("URL that the index gets redirected to [eg. https://yourcompany.com/]: ")
url := readLine()
if url == "" {
return "https://github.com/Forceu/Gokapi/"
}
if !isValidUrl(url) {
return askForUrl()
}
if !strings.HasSuffix(url, "/") {
url = url + "/"
}
return url
}
func isValidUrl(url string) bool {
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
fmt.Println("URL needs to start with http:// or https://")
return false
}
return true
}
func readLine() string {
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n')
return strings.Replace(text, "\n", "", -1)
}
type Result struct {
Result string `json:"Result"`
FileInfo *FileList `json:"FileInfo"`
Url string `json:"Url"`
}
func createConfigDir() {
if !folderExists(configDir) {
err := os.Mkdir(configDir, 0770)
check(err)
}
}
func isDocker() bool {
return fileExists(".isdocker")
}