refactor: update app instance structure to include both mailserver and logger

This commit is contained in:
2024-08-18 13:35:07 +07:00
parent 7df02c270b
commit d64a4a587e
23 changed files with 147 additions and 225 deletions

View File

@ -1,48 +1,29 @@
package app
import (
"fmt"
"github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/middleware"
"github.com/fossyy/filekeeper/routes"
"github.com/fossyy/filekeeper/utils"
"github.com/fossyy/filekeeper/email"
"github.com/fossyy/filekeeper/logger"
"net/http"
)
type App struct {
http.Server
DB db.Database
}
var Server App
func NewServer(addr string, handler http.Handler, database db.Database) App {
type App struct {
http.Server
DB *db.Database
Logger *logger.AggregatedLogger
Mail *email.SmtpServer
}
func NewServer(addr string, handler http.Handler, logger logger.AggregatedLogger, database db.Database, mail email.SmtpServer) App {
return App{
Server: http.Server{
Addr: addr,
Handler: handler,
},
DB: database,
}
}
func Start() {
serverAddr := fmt.Sprintf("%s:%s", utils.Getenv("SERVER_HOST"), utils.Getenv("SERVER_PORT"))
dbUser := utils.Getenv("DB_USERNAME")
dbPass := utils.Getenv("DB_PASSWORD")
dbHost := utils.Getenv("DB_HOST")
dbPort := utils.Getenv("DB_PORT")
dbName := utils.Getenv("DB_NAME")
database := db.NewPostgresDB(dbUser, dbPass, dbHost, dbPort, dbName, db.DisableSSL)
db.DB = database
Server = NewServer(serverAddr, middleware.Handler(routes.SetupRoutes()), database)
fmt.Printf("Listening on http://%s\n", Server.Addr)
err := Server.ListenAndServe()
if err != nil {
panic(err)
return
Logger: &logger,
DB: &database,
Mail: &mail,
}
}

12
cache/cache.go vendored
View File

@ -2,8 +2,8 @@ package cache
import (
"fmt"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/utils"
"github.com/google/uuid"
"sync"
@ -33,12 +33,10 @@ type FileWithExpired struct {
mu sync.Mutex
}
var log *logger.AggregatedLogger
var userCache map[string]*UserWithExpired
var fileCache map[string]*FileWithExpired
func init() {
log = logger.Logger()
userCache = make(map[string]*UserWithExpired)
fileCache = make(map[string]*FileWithExpired)
@ -50,7 +48,7 @@ func init() {
currentTime := time.Now()
cacheClean := 0
cleanID := utils.GenerateRandomString(10)
log.Info(fmt.Sprintf("Cache cleanup [user] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [user] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
for _, user := range userCache {
user.mu.Lock()
@ -61,7 +59,7 @@ func init() {
user.mu.Unlock()
}
log.Info(fmt.Sprintf("Cache cleanup [user] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [user] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
}
}()
@ -71,7 +69,7 @@ func init() {
currentTime := time.Now()
cacheClean := 0
cleanID := utils.GenerateRandomString(10)
log.Info(fmt.Sprintf("Cache cleanup [files] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [files] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
for _, file := range fileCache {
file.mu.Lock()
@ -84,7 +82,7 @@ func init() {
file.mu.Unlock()
}
log.Info(fmt.Sprintf("Cache cleanup [files] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [files] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
}
}()
}

View File

@ -15,8 +15,8 @@ type Email interface {
Send()
}
func NewSmtpServer(Host string, Port int, User string, Password string) *SmtpServer {
return &SmtpServer{
func NewSmtpServer(Host string, Port int, User string, Password string) SmtpServer {
return SmtpServer{
Host: Host,
Port: Port,
User: User,

View File

@ -5,11 +5,11 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/cache"
"github.com/fossyy/filekeeper/db"
googleOauthSetupHandler "github.com/fossyy/filekeeper/handler/auth/google/setup"
signinHandler "github.com/fossyy/filekeeper/handler/signin"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/utils"
@ -53,11 +53,10 @@ type CsrfToken struct {
mu sync.Mutex
}
var log *logger.AggregatedLogger
var CsrfTokens map[string]*CsrfToken
func init() {
log = logger.Logger()
CsrfTokens = make(map[string]*CsrfToken)
ticker := time.NewTicker(time.Minute)
@ -67,7 +66,7 @@ func init() {
currentTime := time.Now()
cacheClean := 0
cleanID := utils.GenerateRandomString(10)
log.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
for _, data := range CsrfTokens {
data.mu.Lock()
@ -78,7 +77,7 @@ func init() {
data.mu.Unlock()
}
log.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [csrf_token] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
}
}()
}
@ -108,7 +107,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
resp, err := http.Post("https://oauth2.googleapis.com/token", "application/x-www-form-urlencoded", bytes.NewBufferString(formData.Encode()))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error("Error:", err)
app.Server.Logger.Error("Error:", err)
return
}
defer resp.Body.Close()
@ -116,7 +115,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
var oauthData OauthToken
if err := json.NewDecoder(resp.Body).Decode(&oauthData); err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error("Error reading token response body:", err)
app.Server.Logger.Error("Error reading token response body:", err)
return
}
@ -126,7 +125,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
req.Header.Set("Authorization", "Bearer "+oauthData.AccessToken)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error("Error creating user info request:", err)
app.Server.Logger.Error("Error creating user info request:", err)
return
}
@ -136,13 +135,13 @@ func GET(w http.ResponseWriter, r *http.Request) {
var oauthUser OauthUser
if err := json.NewDecoder(userInfoResp.Body).Decode(&oauthUser); err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error("Error reading user info response body:", err)
app.Server.Logger.Error("Error reading user info response body:", err)
return
}
if oauthUser.Email == "" {
w.WriteHeader(http.StatusInternalServerError)
log.Error("Error reading user info response body: email not found")
app.Server.Logger.Error("Error reading user info response body: email not found")
return
}
@ -161,7 +160,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}

View File

@ -2,25 +2,19 @@ package googleOauthHandler
import (
"fmt"
"github.com/fossyy/filekeeper/app"
googleOauthCallbackHandler "github.com/fossyy/filekeeper/handler/auth/google/callback"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/utils"
"net/http"
"time"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func GET(w http.ResponseWriter, r *http.Request) {
token, err := utils.GenerateCSRFToken()
googleOauthCallbackHandler.CsrfTokens[token] = &googleOauthCallbackHandler.CsrfToken{Token: token, CreateTime: time.Now()}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
http.Redirect(w, r, fmt.Sprintf("https://accounts.google.com/o/oauth2/auth?scope=email profile&response_type=code&access_type=offline&state=%s&redirect_uri=%s&client_id=%s", token, utils.Getenv("GOOGLE_CALLBACK"), utils.Getenv("GOOGLE_CLIENT_ID")), http.StatusFound)

View File

@ -2,9 +2,9 @@ package googleOauthSetupHandler
import (
"fmt"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/db"
signinHandler "github.com/fossyy/filekeeper/handler/signin"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/types/models"
@ -24,11 +24,10 @@ type UnregisteredUser struct {
mu sync.Mutex
}
var log *logger.AggregatedLogger
var SetupUser map[string]*UnregisteredUser
func init() {
log = logger.Logger()
SetupUser = make(map[string]*UnregisteredUser)
ticker := time.NewTicker(time.Minute)
@ -38,7 +37,7 @@ func init() {
currentTime := time.Now()
cacheClean := 0
cleanID := utils.GenerateRandomString(10)
log.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
for _, data := range SetupUser {
data.mu.Lock()
@ -50,7 +49,7 @@ func init() {
data.mu.Unlock()
}
log.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [GoogleSetup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
}
}()
}
@ -68,7 +67,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}
@ -83,7 +82,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
username := r.Form.Get("username")
@ -98,7 +97,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -122,7 +121,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return

View File

@ -1,21 +1,15 @@
package downloadHandler
import (
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/view/client/download"
"net/http"
"github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/utils"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func GET(w http.ResponseWriter, r *http.Request) {
userSession := r.Context().Value("user").(types.User)
files, err := db.DB.GetFiles(userSession.UserID.String())
@ -38,7 +32,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}

View File

@ -1,26 +1,20 @@
package downloadFileHandler
import (
"github.com/fossyy/filekeeper/app"
"net/http"
"os"
"path/filepath"
"github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/logger"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func GET(w http.ResponseWriter, r *http.Request) {
fileID := r.PathValue("id")
file, err := db.DB.GetFile(fileID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
@ -31,7 +25,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
saveFolder := filepath.Join(basePath, file.OwnerID.String(), file.ID.String())
if filepath.Dir(saveFolder) != filepath.Join(basePath, file.OwnerID.String()) {
log.Error("invalid path")
app.Server.Logger.Error("invalid path")
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -39,7 +33,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
openFile, err := os.OpenFile(filepath.Join(saveFolder, file.Name), os.O_RDONLY, 0)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
defer openFile.Close()
@ -47,7 +41,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
stat, err := openFile.Stat()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}

View File

@ -2,24 +2,17 @@ package errorHandler
import (
"fmt"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/view/client/error"
"net/http"
"github.com/fossyy/filekeeper/logger"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func NotFound(w http.ResponseWriter, r *http.Request) {
component := errorView.NotFound("Not Found")
err := component.Render(r.Context(), w)
if err != nil {
fmt.Fprint(w, err.Error())
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}
@ -29,7 +22,7 @@ func InternalServerError(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
fmt.Fprint(w, err.Error())
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}

View File

@ -5,17 +5,15 @@ import (
"context"
"errors"
"fmt"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/cache"
"github.com/fossyy/filekeeper/view/client/email"
"github.com/fossyy/filekeeper/view/client/forgotPassword"
"github.com/google/uuid"
"net/http"
"strconv"
"sync"
"time"
"github.com/fossyy/filekeeper/email"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/types/models"
"github.com/fossyy/filekeeper/utils"
@ -29,25 +27,19 @@ type ForgotPassword struct {
CreateTime time.Time
}
var log *logger.AggregatedLogger
var mailServer *email.SmtpServer
var ListForgotPassword map[string]*ForgotPassword
var UserForgotPassword = make(map[string]string)
func init() {
log = logger.Logger()
ListForgotPassword = make(map[string]*ForgotPassword)
smtpPort, _ := strconv.Atoi(utils.Getenv("SMTP_PORT"))
mailServer = email.NewSmtpServer(utils.Getenv("SMTP_HOST"), smtpPort, utils.Getenv("SMTP_USER"), utils.Getenv("SMTP_PASSWORD"))
ticker := time.NewTicker(time.Minute)
//TESTING
go func() {
for {
<-ticker.C
currentTime := time.Now()
cacheClean := 0
cleanID := utils.GenerateRandomString(10)
log.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
for _, data := range ListForgotPassword {
data.mu.Lock()
@ -59,7 +51,7 @@ func init() {
data.mu.Unlock()
}
log.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Forgot Password] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
}
}()
}
@ -72,7 +64,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}
@ -81,7 +73,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, "Error parsing form", http.StatusBadRequest)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
@ -96,7 +88,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -112,7 +104,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err = verifyForgot(userData)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
@ -120,7 +112,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -152,7 +144,7 @@ func verifyForgot(user *models.User) error {
UserForgotPassword[code] = user.Email
ListForgotPassword[user.Email] = userData
err = mailServer.Send(user.Email, "Password Change Request", buffer.String())
err = app.Server.Mail.Send(user.Email, "Password Change Request", buffer.String())
if err != nil {
return err
}

View File

@ -1,10 +1,10 @@
package forgotPasswordVerifyHandler
import (
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/cache"
"github.com/fossyy/filekeeper/db"
forgotPasswordHandler "github.com/fossyy/filekeeper/handler/forgotPassword"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/utils"
@ -13,10 +13,8 @@ import (
"net/http"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
//TESTING
}
@ -39,7 +37,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}
@ -58,7 +56,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
@ -72,7 +70,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -81,14 +79,14 @@ func POST(w http.ResponseWriter, r *http.Request) {
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
err = db.DB.UpdateUserPassword(data.User.Email, hashedPassword)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
@ -103,7 +101,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return

View File

@ -1,26 +1,19 @@
package indexHandler
import (
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/view/client/index"
"net/http"
"github.com/fossyy/filekeeper/logger"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func GET(w http.ResponseWriter, r *http.Request) {
_, userSession, _ := session.GetSession(r)
component := indexView.Main("Secure File Hosting - Filekeeper", userSession)
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}

View File

@ -3,8 +3,8 @@ package signinHandler
import (
"errors"
"github.com/a-h/templ"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/cache"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/utils"
@ -13,7 +13,6 @@ import (
"strings"
)
var log *logger.AggregatedLogger
var errorMessages = make(map[string]string)
func init() {
@ -39,7 +38,7 @@ func init() {
"account_selection_required": "Please select an account to proceed with the request.",
"consent_required": "Consent is required to proceed. Please provide consent to continue.",
}
log = logger.Logger()
}
func GET(w http.ResponseWriter, r *http.Request) {
@ -64,7 +63,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}
@ -73,7 +72,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, "Error parsing form", http.StatusBadRequest)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
email := r.Form.Get("email")
@ -84,11 +83,11 @@ func POST(w http.ResponseWriter, r *http.Request) {
Code: 0,
Message: "Incorrect Username or Password",
})
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -152,7 +151,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}

View File

@ -4,16 +4,14 @@ import (
"bytes"
"context"
"fmt"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/view/client/email"
signupView "github.com/fossyy/filekeeper/view/client/signup"
"net/http"
"strconv"
"sync"
"time"
"github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/email"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/types/models"
"github.com/fossyy/filekeeper/utils"
@ -27,15 +25,10 @@ type UnverifiedUser struct {
CreateTime time.Time
}
var log *logger.AggregatedLogger
var mailServer *email.SmtpServer
var VerifyUser map[string]*UnverifiedUser
var VerifyEmail map[string]string
func init() {
log = logger.Logger()
smtpPort, _ := strconv.Atoi(utils.Getenv("SMTP_PORT"))
mailServer = email.NewSmtpServer(utils.Getenv("SMTP_HOST"), smtpPort, utils.Getenv("SMTP_USER"), utils.Getenv("SMTP_PASSWORD"))
VerifyUser = make(map[string]*UnverifiedUser)
VerifyEmail = make(map[string]string)
@ -46,7 +39,7 @@ func init() {
currentTime := time.Now()
cacheClean := 0
cleanID := utils.GenerateRandomString(10)
log.Info(fmt.Sprintf("Cache cleanup [signup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [signup] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
for _, data := range VerifyUser {
data.mu.Lock()
@ -58,7 +51,7 @@ func init() {
data.mu.Unlock()
}
log.Info(fmt.Sprintf("Cache cleanup [signup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [signup] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
}
}()
}
@ -71,7 +64,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}
@ -80,7 +73,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
userEmail := r.Form.Get("email")
@ -95,7 +88,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -117,7 +110,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -126,7 +119,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err = verifyEmail(&newUser)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
@ -134,7 +127,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -167,7 +160,7 @@ func verifyEmail(user *models.User) error {
VerifyUser[code] = &unverifiedUser
VerifyEmail[user.Email] = code
err = mailServer.Send(user.Email, "Account Registration Verification", buffer.String())
err = app.Server.Mail.Send(user.Email, "Account Registration Verification", buffer.String())
if err != nil {
return err
}

View File

@ -1,21 +1,15 @@
package signupVerifyHandler
import (
"github.com/fossyy/filekeeper/app"
signupView "github.com/fossyy/filekeeper/view/client/signup"
"net/http"
"github.com/fossyy/filekeeper/db"
signupHandler "github.com/fossyy/filekeeper/handler/signup"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/types"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func GET(w http.ResponseWriter, r *http.Request) {
code := r.PathValue("code")
data, ok := signupHandler.VerifyUser[code]
@ -34,7 +28,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
return
@ -48,7 +42,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err = component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}

View File

@ -3,6 +3,7 @@ package initialisation
import (
"encoding/json"
"errors"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/cache"
"io"
"net/http"
@ -10,19 +11,12 @@ import (
"path/filepath"
"github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/types/models"
"github.com/google/uuid"
"gorm.io/gorm"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func POST(w http.ResponseWriter, r *http.Request) {
userSession := r.Context().Value("user").(types.User)
@ -64,10 +58,10 @@ func POST(w http.ResponseWriter, r *http.Request) {
func handleNewUpload(user types.User, file types.FileInfo) (models.File, error) {
uploadDir := "uploads"
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
err := os.Mkdir(uploadDir, os.ModePerm)
if err != nil {
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return models.File{}, err
}
}
@ -84,7 +78,7 @@ func handleNewUpload(user types.User, file types.FileInfo) (models.File, error)
err := os.MkdirAll(saveFolder, os.ModePerm)
if err != nil {
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return models.File{}, err
}
@ -101,7 +95,7 @@ func handleNewUpload(user types.User, file types.FileInfo) (models.File, error)
err = db.DB.CreateFile(&newFile)
if err != nil {
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return models.File{}, err
}
@ -122,5 +116,5 @@ func respondErrorJSON(w http.ResponseWriter, err error, statusCode int) {
func handleError(w http.ResponseWriter, err error, statusCode int) {
http.Error(w, err.Error(), statusCode)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
}

View File

@ -1,8 +1,8 @@
package uploadHandler
import (
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/cache"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/types"
filesView "github.com/fossyy/filekeeper/view/client/upload"
"io"
@ -12,12 +12,6 @@ import (
"strconv"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
func GET(w http.ResponseWriter, r *http.Request) {
component := filesView.Main("Filekeeper - Upload")
if err := component.Render(r.Context(), w); err != nil {
@ -38,7 +32,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
uploadDir := "uploads"
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
if err := os.Mkdir(uploadDir, os.ModePerm); err != nil {
log.Error("error getting upload info: " + err.Error())
app.Server.Logger.Error("error getting upload info: " + err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -46,7 +40,7 @@ func POST(w http.ResponseWriter, r *http.Request) {
file, err := cache.GetFile(fileID)
if err != nil {
log.Error("error getting upload info: " + err.Error())
app.Server.Logger.Error("error getting upload info: " + err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -56,14 +50,14 @@ func POST(w http.ResponseWriter, r *http.Request) {
saveFolder := filepath.Join(basePath, userSession.UserID.String(), file.ID.String())
if filepath.Dir(saveFolder) != filepath.Join(basePath, userSession.UserID.String()) {
log.Error("invalid path")
app.Server.Logger.Error("invalid path")
w.WriteHeader(http.StatusInternalServerError)
return
}
fileByte, fileHeader, err := r.FormFile("chunk")
if err != nil {
log.Error("error getting upload info: " + err.Error())
app.Server.Logger.Error("error getting upload info: " + err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
@ -79,14 +73,14 @@ func POST(w http.ResponseWriter, r *http.Request) {
dst, err := os.OpenFile(filepath.Join(saveFolder, file.Name), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
log.Error("error making upload folder: " + err.Error())
app.Server.Logger.Error("error making upload folder: " + err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
defer dst.Close()
if _, err := io.Copy(dst, fileByte); err != nil {
log.Error("error copying byte to file dst: " + err.Error())
app.Server.Logger.Error("error copying byte to file dst: " + err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}

View File

@ -2,20 +2,14 @@ package userHandler
import (
"github.com/a-h/templ"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/types"
"github.com/fossyy/filekeeper/view/client/user"
"net/http"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/session"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
var errorMessages = map[string]string{
"password_not_match": "The passwords provided do not match. Please try again.",
}
@ -43,7 +37,7 @@ func GET(w http.ResponseWriter, r *http.Request) {
err := component.Render(r.Context(), w)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Error(err.Error())
app.Server.Logger.Error(err.Error())
return
}
}

View File

@ -2,7 +2,6 @@ package logger
import (
"fmt"
"io"
"log"
"os"
"time"
@ -29,11 +28,10 @@ func Logger() *AggregatedLogger {
return &AggregatedLogger{}
}
flag := log.Ldate | log.Ltime
writer := io.MultiWriter(os.Stdout, file)
infoLogger := log.New(writer, "INFO: ", flag)
warnLogger := log.New(writer, "WARN: ", flag)
errorLogger := log.New(writer, "ERROR: ", flag)
panicLogger := log.New(writer, "PANIC: ", flag)
infoLogger := log.New(file, "INFO: ", flag)
warnLogger := log.New(file, "WARN: ", flag)
errorLogger := log.New(file, "ERROR: ", flag)
panicLogger := log.New(file, "PANIC: ", flag)
return &AggregatedLogger{
infoLogger: infoLogger,

34
main.go
View File

@ -1,7 +1,37 @@
package main
import "github.com/fossyy/filekeeper/app"
import (
"fmt"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/db"
"github.com/fossyy/filekeeper/email"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/middleware"
"github.com/fossyy/filekeeper/routes"
"github.com/fossyy/filekeeper/utils"
"strconv"
)
func main() {
app.Start()
serverAddr := fmt.Sprintf("%s:%s", utils.Getenv("SERVER_HOST"), utils.Getenv("SERVER_PORT"))
dbUser := utils.Getenv("DB_USERNAME")
dbPass := utils.Getenv("DB_PASSWORD")
dbHost := utils.Getenv("DB_HOST")
dbPort := utils.Getenv("DB_PORT")
dbName := utils.Getenv("DB_NAME")
database := db.NewPostgresDB(dbUser, dbPass, dbHost, dbPort, dbName, db.DisableSSL)
db.DB = database
smtpPort, _ := strconv.Atoi(utils.Getenv("SMTP_PORT"))
mailServer := email.NewSmtpServer(utils.Getenv("SMTP_HOST"), smtpPort, utils.Getenv("SMTP_USER"), utils.Getenv("SMTP_PASSWORD"))
app.Server = app.NewServer(serverAddr, middleware.Handler(routes.SetupRoutes()), *logger.Logger(), database, mailServer)
fmt.Printf("Listening on http://%s\n", app.Server.Addr)
err := app.Server.ListenAndServe()
if err != nil {
panic(err)
return
}
}

View File

@ -3,21 +3,15 @@ package middleware
import (
"context"
"fmt"
"github.com/fossyy/filekeeper/app"
"net/http"
"strings"
errorHandler "github.com/fossyy/filekeeper/handler/error"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/session"
"github.com/fossyy/filekeeper/utils"
)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
}
type wrapper struct {
http.ResponseWriter
request *http.Request
@ -64,7 +58,7 @@ func Handler(next http.Handler) http.Handler {
writer.Header().Set("Access-Control-Allow-Methods", fmt.Sprintf("%s, OPTIONS", utils.Getenv("CORS_METHODS")))
writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
next.ServeHTTP(wrappedWriter, request)
log.Info(fmt.Sprintf("%s %s %s %v", utils.ClientIP(request), request.Method, request.RequestURI, wrappedWriter.statusCode))
app.Server.Logger.Info(fmt.Sprintf("%s %s %s %v", utils.ClientIP(request), request.Method, request.RequestURI, wrappedWriter.statusCode))
})
}

View File

@ -2,7 +2,7 @@ package session
import (
"fmt"
"github.com/fossyy/filekeeper/logger"
"github.com/fossyy/filekeeper/app"
"github.com/fossyy/filekeeper/types"
"net/http"
"strconv"
@ -41,10 +41,8 @@ const (
var GlobalSessionStore = make(map[string]*Session)
var UserSessionInfoList = make(map[string]map[string]*SessionInfo)
var log *logger.AggregatedLogger
func init() {
log = logger.Logger()
ticker := time.NewTicker(time.Minute)
go func() {
@ -53,7 +51,7 @@ func init() {
currentTime := time.Now()
cacheClean := 0
cleanID := utils.GenerateRandomString(10)
log.Info(fmt.Sprintf("Cache cleanup [Session] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Session] [%s] initiated at %02d:%02d:%02d", cleanID, currentTime.Hour(), currentTime.Minute(), currentTime.Second()))
for _, data := range GlobalSessionStore {
data.mu.Lock()
@ -65,7 +63,7 @@ func init() {
data.mu.Unlock()
}
log.Info(fmt.Sprintf("Cache cleanup [Session] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
app.Server.Logger.Info(fmt.Sprintf("Cache cleanup [Session] [%s] completed: %d entries removed. Finished at %s", cleanID, cacheClean, time.Since(currentTime)))
}
}()
}

View File

@ -5,6 +5,7 @@ import (
"crypto/sha1"
"encoding/base64"
"fmt"
"github.com/fossyy/filekeeper/app"
mathRand "math/rand"
"net/http"
"os"
@ -13,7 +14,6 @@ import (
"time"
"unicode"
"github.com/fossyy/filekeeper/logger"
"github.com/joho/godotenv"
"golang.org/x/crypto/bcrypt"
)
@ -24,7 +24,6 @@ type Env struct {
}
var env *Env
var log *logger.AggregatedLogger
func init() {
env = &Env{value: map[string]string{}}
@ -110,7 +109,7 @@ func Getenv(key string) string {
if os.Getenv("HOSTNAME") == "" {
err := godotenv.Load(".env")
if err != nil {
log.Error("Error loading .env file: %s", err)
app.Server.Logger.Error("Error loading .env file: %s", err)
}
}