diff --git a/internal/auth/auth.go b/internal/auth/auth.go
index 907a3fb..4548776 100644
--- a/internal/auth/auth.go
+++ b/internal/auth/auth.go
@@ -3,15 +3,22 @@ package auth
import (
"time"
"os"
+ "net/http"
"github.com/golang-jwt/jwt/v5"
)
+
+type contextKey string
+const UserContextKey = contextKey("user")
+
+
type Claims struct {
Username string `json:"username"`
jwt.RegisteredClaims
}
+
func CreateToken(username string, expiration time.Time) string {
var signedToken string
var err error
@@ -30,3 +37,18 @@ func CreateToken(username string, expiration time.Time) string {
return signedToken
}
+
+
+func GetUser(r *http.Request) *Claims {
+ var (
+ claims *Claims
+ ok bool
+ )
+
+ claims, ok = r.Context().Value(UserContextKey).(*Claims)
+ if !ok {
+ return nil
+ }
+
+ return claims
+}
diff --git a/internal/controllers/files.go b/internal/controllers/files.go
index 759376f..d43ad47 100644
--- a/internal/controllers/files.go
+++ b/internal/controllers/files.go
@@ -4,48 +4,69 @@ import (
"fmt"
"os"
"io"
+ "time"
"net/http"
"html/template"
"path/filepath"
"mime/multipart"
"github.com/jean0t/EurekaFile/internal/database"
+ "github.com/jean0t/EurekaFile/internal/auth"
"gorm.io/gorm"
)
const basePath string = "internal/views"
-var templ = template.Must(template.ParseFiles(
+func formatDate(t time.Time) string {
+ return t.Format("02 Jan 2006 15:04")
+}
+
+var templ = template.Must(template.New("").Funcs(template.FuncMap{
+ "formatDate": formatDate,
+}).ParseFiles(
filepath.Join(basePath, "files.tmpl"),
filepath.Join(basePath, "upload.tmpl"),
filepath.Join(basePath, "navbar.tmpl"),
))
+type FilesViewData struct {
+ Files []database.File
+}
+
func Files(w http.ResponseWriter, r *http.Request) {
var (
err error
db *gorm.DB
files []database.File
+ data FilesViewData
)
db, err = database.ConnectToDB()
if err != nil {
fmt.Println("[!] Error connecting to database")
+ http.Error(w, "
Internal Server Error
", http.StatusInternalServerError)
+ return
}
files, err = database.GetAllFiles(db)
if err != nil {
fmt.Println("[!] Error fetching all files from the database")
+ http.Error(w, "Internal Server Error
", http.StatusInternalServerError)
+ return
}
- err = templ.ExecuteTemplate(w, "Files", files)
+ data = FilesViewData{Files: files}
+ err = templ.ExecuteTemplate(w, "Files", data)
if err != nil {
fmt.Println("[!] Error executing template for /files")
+ http.Error(w, "Internal Server Error
", http.StatusInternalServerError)
+ return
}
}
+
type UploadPageData struct {
Message string
}
@@ -53,21 +74,44 @@ type UploadPageData struct {
func Upload(w http.ResponseWriter, r *http.Request) {
var (
err error
- file multipart.File
- handler *multipart.FileHeader
- saveDir string
- destination string
- destinationFile *os.File
uploadPageData UploadPageData = UploadPageData{Message: ""}
)
if r.Method == http.MethodPost {
+ var (
+ file multipart.File
+ handler *multipart.FileHeader
+ saveDir string = "./uploaded_files"
+ destination string
+ destinationFile *os.File
+
+ db *gorm.DB
+ user database.User
+ claims *auth.Claims = auth.GetUser(r)
+ )
+
+ db, err = database.ConnectToDB()
+ if err != nil {
+ fmt.Println("[!] Error connecting to database")
+ http.Error(w, "Internal Server Error
", http.StatusInternalServerError)
+ return
+ }
+
+ user, err = database.QueryUser(db, claims.Username)
+ if err != nil {
+ fmt.Println("[!] Failed to query the user, can't save file to database")
+ templ.ExecuteTemplate(w, "Upload", uploadPageData)
+ return
+ }
+
+
err = r.ParseMultipartForm(5 << 20) // 5MB
if err != nil {
fmt.Println("[!] Parse Multipart gave an error")
return
}
+
file, handler, err = r.FormFile("file")
if err != nil {
fmt.Println("[!] Error parsing the uploaded file")
@@ -75,7 +119,7 @@ func Upload(w http.ResponseWriter, r *http.Request) {
}
defer file.Close()
- saveDir = "./uploaded_files"
+
if err = os.MkdirAll(saveDir, os.ModePerm); err != nil {
http.Error(w, "Unable to create save directory: "+err.Error(), http.StatusInternalServerError)
return
@@ -90,17 +134,26 @@ func Upload(w http.ResponseWriter, r *http.Request) {
}
defer destinationFile.Close()
+
if _, err = io.Copy(destinationFile, file); err != nil {
fmt.Println("[!] Error coping file data to server")
return
}
+
+ if err = database.RegisterFile(db, user, handler.Filename); err != nil {
+ fmt.Println("[!] Error registering file data to database")
+ uploadPageData.Message = "File Upload Failed"
+ templ.ExecuteTemplate(w, "Upload", uploadPageData)
+ return
+ }
+
uploadPageData.Message = "File Uploaded Successfully"
templ.ExecuteTemplate(w, "Upload", uploadPageData)
return
}
- templ.ExecuteTemplate(w, "Upload", uploadPageData)
+ err = templ.ExecuteTemplate(w, "Upload", uploadPageData)
if err != nil {
fmt.Println("[!] Error executing template for /upload")
}
diff --git a/internal/controllers/index.go b/internal/controllers/index.go
index c16ad42..f0f26f9 100644
--- a/internal/controllers/index.go
+++ b/internal/controllers/index.go
@@ -11,5 +11,5 @@ func Index(w http.ResponseWriter, r *http.Request) {
filepath.Join("internal", "views", "login.tmpl"),
))
- templ.ExecuteTemplate(w, "Login", nil)
+ _ = templ.ExecuteTemplate(w, "Login", nil)
}
diff --git a/internal/controllers/user.go b/internal/controllers/user.go
index 4a247c2..e338bad 100644
--- a/internal/controllers/user.go
+++ b/internal/controllers/user.go
@@ -18,22 +18,24 @@ func Login(w http.ResponseWriter, r *http.Request) {
var password string = strings.TrimSpace(r.FormValue("password"))
var db *gorm.DB
- if username == "" || password == "" {
- http.Redirect(w, r, "/", http.StatusUnauthorized)
- return
- }
- db, err= database.ConnectToDB()
+ if len(strings.Split(username, "")) < 3 || len(strings.Split(password, "")) < 3 {
+ http.Redirect(w, r, "/", http.StatusUnauthorized)
+ return
+ }
+
+
+ db, err = database.ConnectToDB()
if err != nil {
- fmt.Println("Error connecting to DB")
- http.Redirect(w, r, "/", http.StatusUnauthorized)
+ fmt.Println("[!] Error connecting to DB")
+ http.Error(w, "There was an unexpected error on the server
", http.StatusInternalServerError)
return
}
err = database.IsValidUser(db, username, password)
if err != nil {
fmt.Println("Error validating user")
- http.Redirect(w, r, "/", http.StatusUnauthorized)
+ http.Error(w, "Failed to authenticate
", http.StatusUnauthorized)
return
}
diff --git a/internal/database/files.go b/internal/database/files.go
index 3e80e84..abf9fd2 100644
--- a/internal/database/files.go
+++ b/internal/database/files.go
@@ -10,7 +10,7 @@ func GetAllFiles(db *gorm.DB) ([]File, error) {
err error
)
- err = db.Find(&files).Error
+ err = db.Preload("Author").Find(&files).Error
if err != nil {
return []File{}, err
}
diff --git a/internal/database/user.go b/internal/database/user.go
index 97c3814..85180ed 100644
--- a/internal/database/user.go
+++ b/internal/database/user.go
@@ -23,6 +23,13 @@ func RegisterUser(db *gorm.DB, username, password string) error {
}
+func QueryUser(db *gorm.DB, username string) (User, error) {
+ var user User
+
+ var result = db.Where("username = ?", username).First(&user)
+ return user, result.Error
+}
+
func IsValidUser(db *gorm.DB, username, password string) error {
var user User
var passwordHashed string = HashPassword(password)
diff --git a/internal/middleware/auth.go b/internal/middleware/auth.go
index 8b16fb4..438bae5 100644
--- a/internal/middleware/auth.go
+++ b/internal/middleware/auth.go
@@ -6,13 +6,9 @@ import (
"context"
"github.com/jean0t/EurekaFile/internal/auth"
-
"github.com/golang-jwt/jwt/v5"
)
-type contextKey string
-
-const userContextKey = contextKey("user")
func WithAuth(next http.Handler) http.Handler {
var jwtKey []byte = []byte(os.Getenv("JWT_SECRET"))
@@ -41,17 +37,7 @@ func WithAuth(next http.Handler) http.Handler {
return
}
- var ctx context.Context = context.WithValue(r.Context(), userContextKey, claims)
+ var ctx context.Context = context.WithValue(r.Context(), auth.UserContextKey, claims)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
-
-
-func GetUser(r *http.Request) *auth.Claims {
- claims, ok := r.Context().Value(userContextKey).(*auth.Claims)
- if !ok {
- return nil
- }
-
- return claims
-}
diff --git a/internal/views/files.tmpl b/internal/views/files.tmpl
index 4b037cd..b8bbcda 100644
--- a/internal/views/files.tmpl
+++ b/internal/views/files.tmpl
@@ -33,8 +33,8 @@
{{ range .Files }}
| {{ .Name }} |
- {{ .Author }} |
- {{ .CreatedAt }} |
+ {{ .Author.Username }} |
+ {{ .CreatedAt | formatDate }} |
Download
|