abyss/helpers.go

132 lines
3.0 KiB
Go
Raw Normal View History

2024-10-03 21:19:14 -03:00
package main
import (
2024-10-15 14:18:55 -03:00
"crypto/md5"
"crypto/sha256"
"crypto/subtle"
2024-10-15 14:18:55 -03:00
"encoding/hex"
2024-10-03 21:19:14 -03:00
"fmt"
2024-10-15 14:18:55 -03:00
"io"
2024-10-03 21:19:14 -03:00
"net/http"
2024-10-15 15:08:27 -03:00
"os"
2024-10-17 10:52:33 -03:00
"github.com/golang-jwt/jwt/v5"
2024-10-03 21:19:14 -03:00
)
type FileInfo struct {
Name string
Path string
Size int64
FormattedSize string
Type string
Content string
2024-10-16 22:17:17 -03:00
TimeUploaded string
}
type TemplateData struct {
Files []FileInfo
URL string
}
2024-10-03 21:19:14 -03:00
func CheckAuth(r *http.Request, key string) bool {
2024-10-17 10:52:33 -03:00
receivedKey := r.Header.Get("X-Auth")
if receivedKey == key {
return true
} else if err := validateToken(receivedKey, key); err == nil {
return true
}
return false
}
func validateToken(tokenString, key string) error {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(key), nil
})
if err != nil {
return err
}
if _, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return nil
} else {
return fmt.Errorf("invalid token")
}
2024-10-03 21:19:14 -03:00
}
func FormatFileSize(size int64) string {
if size < 1024 {
return fmt.Sprintf("%d B", size)
} else if size < 1024*1024 {
return fmt.Sprintf("%.2f KB", float64(size)/1024)
} else if size < 1024*1024*1024 {
return fmt.Sprintf("%.2f MB", float64(size)/(1024*1024))
}
return fmt.Sprintf("%.2f GB", float64(size)/(1024*1024*1024))
}
2024-10-15 14:18:55 -03:00
2024-10-15 14:38:01 -03:00
func HashFile(file io.Reader, extension string) (string, error) {
2024-10-15 14:18:55 -03:00
hasher := md5.New()
if _, err := io.Copy(hasher, file); err != nil {
return "", err
}
sha1Hash := hex.EncodeToString(hasher.Sum(nil))[:8]
2024-10-15 14:38:01 -03:00
filename := fmt.Sprintf("%s%s", sha1Hash, extension)
2024-10-15 14:18:55 -03:00
return filename, nil
}
2024-10-15 15:08:27 -03:00
func SaveFile(name string, file io.Reader) error {
dst, err := os.Create(name)
if err != nil {
return err
}
defer dst.Close()
if _, err := io.Copy(dst, file); err != nil {
return err
}
return nil
}
func BasicAuth(next http.HandlerFunc, app *Application) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if ok {
// hash password received
usernameHash := sha256.Sum256([]byte(username))
passwordHash := sha256.Sum256([]byte(password))
// hash our password
expectedUsernameHash := sha256.Sum256([]byte(app.auth.username))
expectedPasswordHash := sha256.Sum256([]byte(app.auth.password))
// compare hashes
usernameMatch := (subtle.ConstantTimeCompare(usernameHash[:], expectedUsernameHash[:]) == 1)
passwordMatch := (subtle.ConstantTimeCompare(passwordHash[:], expectedPasswordHash[:]) == 1)
if usernameMatch && passwordMatch {
next.ServeHTTP(w, r)
return
}
}
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
})
}
2024-10-21 12:01:32 -03:00
func ResponseURLHandler(w http.ResponseWriter, url, filename string) {
pasteURL := fmt.Sprintf("http://%s/%s\n", url, filename)
w.Header().Set("Location", pasteURL)
w.WriteHeader(http.StatusCreated)
fmt.Fprintf(w, "%s", pasteURL)
}