diff --git a/controllers/get.go b/app/controllers/get.go
similarity index 97%
rename from controllers/get.go
rename to app/controllers/get.go
index b054546..404ea66 100644
--- a/controllers/get.go
+++ b/app/controllers/get.go
@@ -2,7 +2,7 @@ package controllers
import (
"GoWeb/app"
- "GoWeb/models"
+ "GoWeb/app/models"
"GoWeb/security"
"GoWeb/templating"
"net/http"
@@ -10,7 +10,7 @@ import (
// Get is a wrapper struct for the App struct
type Get struct {
- App *app.App
+ App *app.Deps
}
func (g *Get) ShowHome(w http.ResponseWriter, _ *http.Request) {
diff --git a/controllers/post.go b/app/controllers/post.go
similarity index 97%
rename from controllers/post.go
rename to app/controllers/post.go
index 5b23050..27c6660 100644
--- a/controllers/post.go
+++ b/app/controllers/post.go
@@ -2,7 +2,7 @@ package controllers
import (
"GoWeb/app"
- "GoWeb/models"
+ "GoWeb/app/models"
"log/slog"
"net/http"
"time"
@@ -10,7 +10,7 @@ import (
// Post is a wrapper struct for the App struct
type Post struct {
- App *app.App
+ App *app.Deps
}
func (p *Post) Login(w http.ResponseWriter, r *http.Request) {
diff --git a/static/css/style.css b/app/frontend/static/css/style.css
similarity index 100%
rename from static/css/style.css
rename to app/frontend/static/css/style.css
diff --git a/templates/base.html b/app/frontend/templates/base.html
similarity index 82%
rename from templates/base.html
rename to app/frontend/templates/base.html
index 7ad57b9..f4e2ca0 100644
--- a/templates/base.html
+++ b/app/frontend/templates/base.html
@@ -3,7 +3,7 @@
SiteName - {{ template "pageTitle" }}
-
+
{{ template "content" . }}
diff --git a/templates/pages/home.html b/app/frontend/templates/pages/home.html
similarity index 100%
rename from templates/pages/home.html
rename to app/frontend/templates/pages/home.html
diff --git a/templates/pages/login.html b/app/frontend/templates/pages/login.html
similarity index 100%
rename from templates/pages/login.html
rename to app/frontend/templates/pages/login.html
diff --git a/templates/pages/register.html b/app/frontend/templates/pages/register.html
similarity index 100%
rename from templates/pages/register.html
rename to app/frontend/templates/pages/register.html
diff --git a/app/app.go b/app/globals.go
similarity index 80%
rename from app/app.go
rename to app/globals.go
index 53db2ec..e3985c7 100644
--- a/app/app.go
+++ b/app/globals.go
@@ -6,8 +6,8 @@ import (
"embed"
)
-// App contains and supplies available configurations and connections
-type App struct {
+// Deps contains and supplies available configurations and connections
+type Deps struct {
Config config.Configuration // Configuration file
Db *sql.DB // Database connection
Res *embed.FS // Resources from the embedded filesystem
diff --git a/middleware/csrf.go b/app/middleware/csrf.go
similarity index 100%
rename from middleware/csrf.go
rename to app/middleware/csrf.go
diff --git a/middleware/wrapper.go b/app/middleware/wrapper.go
similarity index 80%
rename from middleware/wrapper.go
rename to app/middleware/wrapper.go
index ce0d4e6..5e0cf28 100644
--- a/middleware/wrapper.go
+++ b/app/middleware/wrapper.go
@@ -2,6 +2,8 @@ package middleware
import "net/http"
+type MiddlewareFunc func(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request)
+
// ProcessGroup is a wrapper function for the http.HandleFunc function
// that takes the function you want to execute (f) and the middleware you want
// to execute (m) this should be used when processing multiple groups of middleware at a time
diff --git a/models/migrations.go b/app/models/migrations.go
similarity index 94%
rename from models/migrations.go
rename to app/models/migrations.go
index a26b595..9bdac20 100644
--- a/models/migrations.go
+++ b/app/models/migrations.go
@@ -7,7 +7,7 @@ import (
)
// RunAllMigrations defines the structs that should be represented in the database
-func RunAllMigrations(app *app.App) error {
+func RunAllMigrations(app *app.Deps) error {
// Declare new dummy user for reflection
user := User{
Id: 1, // Id is handled automatically, but it is added here to show it will be skipped during column creation
diff --git a/models/session.go b/app/models/session.go
similarity index 89%
rename from models/session.go
rename to app/models/session.go
index eae0ac1..438453e 100644
--- a/models/session.go
+++ b/app/models/session.go
@@ -31,7 +31,7 @@ const (
)
// CreateSession creates a new session for a user
-func CreateSession(app *app.App, w http.ResponseWriter, userId int64, remember bool) (Session, error) {
+func CreateSession(app *app.Deps, w http.ResponseWriter, userId int64, remember bool) (Session, error) {
session := Session{}
session.UserId = userId
session.AuthToken = generateAuthToken(app)
@@ -62,7 +62,7 @@ func CreateSession(app *app.App, w http.ResponseWriter, userId int64, remember b
return session, nil
}
-func SessionByAuthToken(app *app.App, authToken string) (Session, error) {
+func SessionByAuthToken(app *app.Deps, authToken string) (Session, error) {
session := Session{}
err := app.Db.QueryRow(selectSessionByAuthToken, authToken).Scan(&session.Id, &session.UserId, &session.AuthToken, &session.RememberMe, &session.CreatedAt)
@@ -74,7 +74,7 @@ func SessionByAuthToken(app *app.App, authToken string) (Session, error) {
}
// generateAuthToken generates a random 64-byte string
-func generateAuthToken(app *app.App) string {
+func generateAuthToken(app *app.Deps) string {
b := make([]byte, 64)
_, err := rand.Read(b)
if err != nil {
@@ -85,7 +85,7 @@ func generateAuthToken(app *app.App) string {
}
// createSessionCookie creates a new session cookie
-func createSessionCookie(app *app.App, w http.ResponseWriter, session Session) {
+func createSessionCookie(app *app.Deps, w http.ResponseWriter, session Session) {
cookie := &http.Cookie{}
if session.RememberMe {
cookie = &http.Cookie{
@@ -111,7 +111,7 @@ func createSessionCookie(app *app.App, w http.ResponseWriter, session Session) {
}
// deleteSessionCookie deletes the session cookie
-func deleteSessionCookie(app *app.App, w http.ResponseWriter) {
+func deleteSessionCookie(app *app.Deps, w http.ResponseWriter) {
cookie := &http.Cookie{
Name: "session",
Value: "",
@@ -123,7 +123,7 @@ func deleteSessionCookie(app *app.App, w http.ResponseWriter) {
}
// DeleteSessionByAuthToken deletes a session from the database by AuthToken
-func DeleteSessionByAuthToken(app *app.App, w http.ResponseWriter, authToken string) error {
+func DeleteSessionByAuthToken(app *app.Deps, w http.ResponseWriter, authToken string) error {
_, err := app.Db.Exec(deleteSessionByAuthToken, authToken)
if err != nil {
slog.Error("error deleting session from database")
@@ -136,7 +136,7 @@ func DeleteSessionByAuthToken(app *app.App, w http.ResponseWriter, authToken str
}
// ScheduledSessionCleanup deletes expired sessions from the database
-func ScheduledSessionCleanup(app *app.App) {
+func ScheduledSessionCleanup(app *app.Deps) {
// Delete sessions older than 30 days (remember me sessions)
_, err := app.Db.Exec(deleteSessionsOlderThan30Days)
if err != nil {
diff --git a/models/user.go b/app/models/user.go
similarity index 86%
rename from models/user.go
rename to app/models/user.go
index 3940e0a..4880e5f 100644
--- a/models/user.go
+++ b/app/models/user.go
@@ -30,7 +30,7 @@ const (
)
// CurrentUser finds the currently logged-in user by session cookie
-func CurrentUser(app *app.App, r *http.Request) (User, error) {
+func CurrentUser(app *app.Deps, r *http.Request) (User, error) {
cookie, err := r.Cookie("session")
if err != nil {
return User{}, err
@@ -45,7 +45,7 @@ func CurrentUser(app *app.App, r *http.Request) (User, error) {
}
// UserById finds a User table row in the database by id and returns a struct representing this row
-func UserById(app *app.App, id int64) (User, error) {
+func UserById(app *app.Deps, id int64) (User, error) {
user := User{}
err := app.Db.QueryRow(selectUserById, id).Scan(&user.Id, &user.Username, &user.Password, &user.CreatedAt, &user.UpdatedAt)
@@ -57,7 +57,7 @@ func UserById(app *app.App, id int64) (User, error) {
}
// UserByUsername finds a User table row in the database by username and returns a struct representing this row
-func UserByUsername(app *app.App, username string) (User, error) {
+func UserByUsername(app *app.Deps, username string) (User, error) {
user := User{}
err := app.Db.QueryRow(selectUserByUsername, username).Scan(&user.Id, &user.Username, &user.Password, &user.CreatedAt, &user.UpdatedAt)
@@ -69,7 +69,7 @@ func UserByUsername(app *app.App, username string) (User, error) {
}
// CreateUser creates a User table row in the database
-func CreateUser(app *app.App, username string, password string, createdAt time.Time, updatedAt time.Time) (User, error) {
+func CreateUser(app *app.Deps, username string, password string, createdAt time.Time, updatedAt time.Time) (User, error) {
// Get sha256 hash of password then get bcrypt hash to store
hash256 := sha256.New()
hash256.Write([]byte(password))
@@ -93,7 +93,7 @@ func CreateUser(app *app.App, username string, password string, createdAt time.T
}
// AuthenticateUser validates the password for the specified user
-func AuthenticateUser(app *app.App, w http.ResponseWriter, username string, password string, remember bool) (Session, error) {
+func AuthenticateUser(app *app.Deps, w http.ResponseWriter, username string, password string, remember bool) (Session, error) {
var user User
err := app.Db.QueryRow(selectUserByUsername, username).Scan(&user.Id, &user.Username, &user.Password, &user.CreatedAt, &user.UpdatedAt)
@@ -117,7 +117,7 @@ func AuthenticateUser(app *app.App, w http.ResponseWriter, username string, pass
}
// LogoutUser deletes the session cookie and AuthToken from the database
-func LogoutUser(app *app.App, w http.ResponseWriter, r *http.Request) {
+func LogoutUser(app *app.Deps, w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session")
if err != nil {
return
diff --git a/routes/get.go b/app/routes/get.go
similarity index 93%
rename from routes/get.go
rename to app/routes/get.go
index 5282fb8..28089d2 100644
--- a/routes/get.go
+++ b/app/routes/get.go
@@ -2,14 +2,14 @@ package routes
import (
"GoWeb/app"
- "GoWeb/controllers"
+ "GoWeb/app/controllers"
"io/fs"
"log/slog"
"net/http"
)
// Get defines all project get routes
-func Get(app *app.App) {
+func Get(app *app.Deps) {
// Get controller struct initialize
getController := controllers.Get{
App: app,
diff --git a/routes/post.go b/app/routes/post.go
similarity index 82%
rename from routes/post.go
rename to app/routes/post.go
index ebda5d1..344d8f4 100644
--- a/routes/post.go
+++ b/app/routes/post.go
@@ -2,13 +2,13 @@ package routes
import (
"GoWeb/app"
- "GoWeb/controllers"
- "GoWeb/middleware"
+ "GoWeb/app/controllers"
+ "GoWeb/app/middleware"
"net/http"
)
// Post defines all project post routes
-func Post(app *app.App) {
+func Post(app *app.Deps) {
// Post controller struct initialize
postController := controllers.Post{
App: app,
diff --git a/app/schedule.go b/app/scheduler.go
similarity index 76%
rename from app/schedule.go
rename to app/scheduler.go
index 56b4b9a..d18d704 100644
--- a/app/schedule.go
+++ b/app/scheduler.go
@@ -6,22 +6,22 @@ import (
)
type Scheduled struct {
- EveryReboot []func(app *App)
- EverySecond []func(app *App)
- EveryMinute []func(app *App)
- EveryHour []func(app *App)
- EveryDay []func(app *App)
- EveryWeek []func(app *App)
- EveryMonth []func(app *App)
- EveryYear []func(app *App)
+ EveryReboot []func(app *Deps)
+ EverySecond []func(app *Deps)
+ EveryMinute []func(app *Deps)
+ EveryHour []func(app *Deps)
+ EveryDay []func(app *Deps)
+ EveryWeek []func(app *Deps)
+ EveryMonth []func(app *Deps)
+ EveryYear []func(app *Deps)
}
type Task struct {
- Funcs []func(app *App)
+ Funcs []func(app *Deps)
Interval time.Duration
}
-func RunScheduledTasks(app *App, poolSize int, stop <-chan struct{}) {
+func RunScheduledTasks(app *Deps, poolSize int, stop <-chan struct{}) {
for _, f := range app.ScheduledTasks.EveryReboot {
f(app)
}
@@ -51,7 +51,7 @@ func RunScheduledTasks(app *App, poolSize int, stop <-chan struct{}) {
case <-ticker.C:
for _, f := range task.Funcs {
runner <- true
- go func(f func(app *App)) {
+ go func(f func(app *Deps)) {
defer func() { <-runner }()
f(app)
}(f)
diff --git a/database/connection.go b/database/connection.go
index 3978599..c36b088 100644
--- a/database/connection.go
+++ b/database/connection.go
@@ -9,7 +9,7 @@ import (
)
// Connect returns a new database connection
-func Connect(app *app.App) *sql.DB {
+func Connect(app *app.Deps) *sql.DB {
postgresConfig := fmt.Sprintf("host=%s port=%s user=%s "+
"password=%s dbname=%s sslmode=disable",
app.Config.Db.Ip, app.Config.Db.Port, app.Config.Db.User, app.Config.Db.Password, app.Config.Db.Name)
diff --git a/database/migrate.go b/database/migrate.go
index 69f9ac6..a5b42dc 100644
--- a/database/migrate.go
+++ b/database/migrate.go
@@ -11,7 +11,7 @@ import (
// Migrate given a dummy object of any type, it will create a table with the same name
// as the type and create columns with the same name as the fields of the object
-func Migrate(app *app.App, anyStruct interface{}) error {
+func Migrate(app *app.Deps, anyStruct interface{}) error {
valueOfStruct := reflect.ValueOf(anyStruct)
typeOfStruct := valueOfStruct.Type()
@@ -41,7 +41,7 @@ func Migrate(app *app.App, anyStruct interface{}) error {
}
// createTable creates a table with the given name if it doesn't exist, it is assumed that id will be the primary key
-func createTable(app *app.App, tableName string) error {
+func createTable(app *app.Deps, tableName string) error {
var tableExists bool
err := app.Db.QueryRow("SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname ~ $1 AND pg_catalog.pg_table_is_visible(c.oid))", "^"+tableName+"$").Scan(&tableExists)
if err != nil {
@@ -67,7 +67,7 @@ func createTable(app *app.App, tableName string) error {
}
// createColumn creates a column with the given name and type if it doesn't exist
-func createColumn(app *app.App, tableName, columnName, columnType string) error {
+func createColumn(app *app.Deps, tableName, columnName, columnType string) error {
var columnExists bool
err := app.Db.QueryRow("SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = $1 AND column_name = $2)", tableName, columnName).Scan(&columnExists)
if err != nil {
diff --git a/env_example.json b/env_example.json
index 53754ff..e70c6d8 100644
--- a/env_example.json
+++ b/env_example.json
@@ -12,7 +12,7 @@
"HttpPort": "8090"
},
"Template": {
- "BaseTemplateName": "templates/base.html",
- "ContentPath": "templates"
+ "BaseTemplateName": "app/frontend/templates/base.html",
+ "ContentPath": "app/frontend/templates"
}
}
\ No newline at end of file
diff --git a/main.go b/main.go
index 7251d8c..54f6e60 100644
--- a/main.go
+++ b/main.go
@@ -2,10 +2,10 @@ package main
import (
"GoWeb/app"
+ "GoWeb/app/models"
+ "GoWeb/app/routes"
"GoWeb/config"
"GoWeb/database"
- "GoWeb/models"
- "GoWeb/routes"
"GoWeb/templating"
"context"
"embed"
@@ -18,12 +18,12 @@ import (
"time"
)
-//go:embed templates static
+//go:embed app/frontend/templates app/frontend/static
var res embed.FS
func main() {
- // Create instance of App
- appLoaded := app.App{}
+ // Create instance of Deps
+ appLoaded := app.Deps{}
// Load config file to application
appLoaded.Config = config.LoadConfig()
@@ -60,8 +60,8 @@ func main() {
// Assign and run scheduled tasks
appLoaded.ScheduledTasks = app.Scheduled{
- EveryReboot: []func(app *app.App){models.ScheduledSessionCleanup},
- EveryMinute: []func(app *app.App){models.ScheduledSessionCleanup},
+ EveryReboot: []func(app *app.Deps){models.ScheduledSessionCleanup},
+ EveryMinute: []func(app *app.Deps){models.ScheduledSessionCleanup},
}
// Define Routes
diff --git a/middleware/groups.go b/middleware/groups.go
deleted file mode 100644
index 0bb20a4..0000000
--- a/middleware/groups.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package middleware
-
-import "net/http"
-
-type MiddlewareFunc func(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request)
diff --git a/restclient/client.go b/rest/client.go
similarity index 98%
rename from restclient/client.go
rename to rest/client.go
index 519f62b..e409047 100644
--- a/restclient/client.go
+++ b/rest/client.go
@@ -1,4 +1,4 @@
-package restclient
+package rest
import (
"bytes"
diff --git a/templating/templateHelper.go b/templating/builder.go
similarity index 96%
rename from templating/templateHelper.go
rename to templating/builder.go
index 73def88..d8c1de6 100644
--- a/templating/templateHelper.go
+++ b/templating/builder.go
@@ -9,9 +9,9 @@ import (
"net/http"
)
-var templates = make(map[string]*template.Template) // This is only used here, does not need to be in app.App
+var templates = make(map[string]*template.Template) // This is only used here, does not need to be in app.Deps
-func BuildPages(app *app.App) error {
+func BuildPages(app *app.Deps) error {
basePath := app.Config.Template.BaseName
baseContent, err := app.Res.ReadFile(basePath)