diff --git a/app/schedule.go b/app/schedule.go index 5820831..87523f5 100644 --- a/app/schedule.go +++ b/app/schedule.go @@ -22,7 +22,6 @@ type Task struct { } func RunScheduledTasks(app *App, poolSize int, stop <-chan struct{}) { - // Run every time the server starts for _, f := range app.ScheduledTasks.EveryReboot { f(app) } @@ -37,7 +36,6 @@ func RunScheduledTasks(app *App, poolSize int, stop <-chan struct{}) { {Interval: 365 * 24 * time.Hour, Funcs: app.ScheduledTasks.EveryYear}, } - // Set up task runners var wg sync.WaitGroup runners := make([]chan bool, len(tasks)) for i, task := range tasks { @@ -65,10 +63,8 @@ func RunScheduledTasks(app *App, poolSize int, stop <-chan struct{}) { }(task, runner) } - // Wait for all goroutines to finish wg.Wait() - // Close channels for _, runner := range runners { close(runner) } diff --git a/config/config.go b/config/config.go index fdf6e17..8ca2691 100644 --- a/config/config.go +++ b/config/config.go @@ -43,7 +43,6 @@ func LoadConfig() Configuration { } }(file) - // Decode json config file to Configuration struct named config decoder := json.NewDecoder(file) Config := Configuration{} err = decoder.Decode(&Config) diff --git a/controllers/get.go b/controllers/get.go new file mode 100644 index 0000000..deeef98 --- /dev/null +++ b/controllers/get.go @@ -0,0 +1,65 @@ +package controllers + +import ( + "GoWeb/app" + "GoWeb/models" + "GoWeb/security" + "GoWeb/templating" + "net/http" +) + +// Get is a wrapper struct for the App struct +type Get struct { + App *app.App +} + +func (g *Get) ShowHome(w http.ResponseWriter, _ *http.Request) { + type dataStruct struct { + Test string + } + + data := dataStruct{ + Test: "Hello World!", + } + + templating.RenderTemplate(g.App, w, "templates/pages/home.html", data) +} + +func (g *Get) ShowRegister(w http.ResponseWriter, r *http.Request) { + type dataStruct struct { + CsrfToken string + } + + CsrfToken, err := security.GenerateCsrfToken(w, r) + if err != nil { + return + } + + data := dataStruct{ + CsrfToken: CsrfToken, + } + + templating.RenderTemplate(g.App, w, "templates/pages/register.html", data) +} + +func (g *Get) ShowLogin(w http.ResponseWriter, r *http.Request) { + type dataStruct struct { + CsrfToken string + } + + CsrfToken, err := security.GenerateCsrfToken(w, r) + if err != nil { + return + } + + data := dataStruct{ + CsrfToken: CsrfToken, + } + + templating.RenderTemplate(g.App, w, "templates/pages/login.html", data) +} + +func (g *Get) Logout(w http.ResponseWriter, r *http.Request) { + models.LogoutUser(g.App, w, r) + http.Redirect(w, r, "/", http.StatusFound) +} diff --git a/controllers/getController.go b/controllers/getController.go deleted file mode 100644 index c4f9a27..0000000 --- a/controllers/getController.go +++ /dev/null @@ -1,67 +0,0 @@ -package controllers - -import ( - "GoWeb/app" - "GoWeb/models" - "GoWeb/security" - "GoWeb/templating" - "net/http" -) - -// GetController is a wrapper struct for the App struct -type GetController struct { - App *app.App -} - -func (getController *GetController) ShowHome(w http.ResponseWriter, _ *http.Request) { - type dataStruct struct { - Test string - } - - data := dataStruct{ - Test: "Hello World!", - } - - templating.RenderTemplate(getController.App, w, "templates/pages/home.html", data) -} - -func (getController *GetController) ShowRegister(w http.ResponseWriter, r *http.Request) { - type dataStruct struct { - CsrfToken string - } - - // Create csrf token - CsrfToken, err := security.GenerateCsrfToken(w, r) - if err != nil { - return - } - - data := dataStruct{ - CsrfToken: CsrfToken, - } - - templating.RenderTemplate(getController.App, w, "templates/pages/register.html", data) -} - -func (getController *GetController) ShowLogin(w http.ResponseWriter, r *http.Request) { - type dataStruct struct { - CsrfToken string - } - - // Create csrf token - CsrfToken, err := security.GenerateCsrfToken(w, r) - if err != nil { - return - } - - data := dataStruct{ - CsrfToken: CsrfToken, - } - - templating.RenderTemplate(getController.App, w, "templates/pages/login.html", data) -} - -func (getController *GetController) Logout(w http.ResponseWriter, r *http.Request) { - models.LogoutUser(getController.App, w, r) - http.Redirect(w, r, "/", http.StatusFound) -} diff --git a/controllers/postController.go b/controllers/post.go similarity index 69% rename from controllers/postController.go rename to controllers/post.go index 1631f98..523f64c 100644 --- a/controllers/postController.go +++ b/controllers/post.go @@ -8,12 +8,12 @@ import ( "time" ) -// PostController is a wrapper struct for the App struct -type PostController struct { +// Post is a wrapper struct for the App struct +type Post struct { App *app.App } -func (postController *PostController) Login(w http.ResponseWriter, r *http.Request) { +func (p *Post) Login(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") remember := r.FormValue("remember") == "on" @@ -23,7 +23,7 @@ func (postController *PostController) Login(w http.ResponseWriter, r *http.Reque http.Redirect(w, r, "/login", http.StatusFound) } - _, err := models.AuthenticateUser(postController.App, w, username, password, remember) + _, err := models.AuthenticateUser(p.App, w, username, password, remember) if err != nil { log.Println("Error authenticating user") log.Println(err) @@ -34,7 +34,7 @@ func (postController *PostController) Login(w http.ResponseWriter, r *http.Reque http.Redirect(w, r, "/", http.StatusFound) } -func (postController *PostController) Register(w http.ResponseWriter, r *http.Request) { +func (p *Post) Register(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") password := r.FormValue("password") createdAt := time.Now() @@ -45,7 +45,7 @@ func (postController *PostController) Register(w http.ResponseWriter, r *http.Re http.Redirect(w, r, "/register", http.StatusFound) } - _, err := models.CreateUser(postController.App, username, password, createdAt, updatedAt) + _, err := models.CreateUser(p.App, username, password, createdAt, updatedAt) if err != nil { log.Println("Error creating user") log.Println(err) diff --git a/database/databaseConnection.go b/database/connection.go similarity index 88% rename from database/databaseConnection.go rename to database/connection.go index 7802000..185ecbe 100644 --- a/database/databaseConnection.go +++ b/database/connection.go @@ -8,8 +8,8 @@ import ( "log" ) -// ConnectDB returns a new database connection -func ConnectDB(app *app.App) *sql.DB { +// Connect returns a new database connection +func Connect(app *app.App) *sql.DB { // Set connection parameters from config postgresConfig := fmt.Sprintf("host=%s port=%s user=%s "+ "password=%s dbname=%s sslmode=disable", diff --git a/database/migrate.go b/database/migrate.go index 7a59aa9..b1885e0 100644 --- a/database/migrate.go +++ b/database/migrate.go @@ -36,7 +36,6 @@ 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 { - // Check to see if the table already exists 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 { @@ -63,7 +62,6 @@ 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 { - // Check to see if the column already exists 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/main.go b/main.go index 42e8ec0..27e7523 100644 --- a/main.go +++ b/main.go @@ -44,7 +44,7 @@ func main() { log.SetOutput(file) // Connect to database and run migrations - appLoaded.Db = database.ConnectDB(&appLoaded) + appLoaded.Db = database.Connect(&appLoaded) if appLoaded.Config.Db.AutoMigrate { err = models.RunAllMigrations(&appLoaded) if err != nil { @@ -60,8 +60,8 @@ func main() { } // Define Routes - routes.GetRoutes(&appLoaded) - routes.PostRoutes(&appLoaded) + routes.Get(&appLoaded) + routes.Post(&appLoaded) // Start server server := &http.Server{Addr: appLoaded.Config.Listen.Ip + ":" + appLoaded.Config.Listen.Port} diff --git a/middleware/csrf.go b/middleware/csrf.go index de3c04c..d86e844 100644 --- a/middleware/csrf.go +++ b/middleware/csrf.go @@ -9,7 +9,6 @@ import ( // Csrf validates the CSRF token and returns the handler function if it succeded func Csrf(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { - // Verify csrf token _, err := security.VerifyCsrfToken(r) if err != nil { log.Println("Error verifying csrf token") diff --git a/models/session.go b/models/session.go index 94100f2..b69976d 100644 --- a/models/session.go +++ b/models/session.go @@ -78,14 +78,12 @@ func GetSessionByAuthToken(app *app.App, authToken string) (Session, error) { // Generates a random 64-byte string func generateAuthToken(app *app.App) string { - // Generate random bytes b := make([]byte, 64) _, err := rand.Read(b) if err != nil { log.Println("Error generating random bytes") } - // Convert random bytes to hex string return hex.EncodeToString(b) } @@ -129,7 +127,6 @@ 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 { - // Delete session from database _, err := app.Db.Exec(deleteSessionByAuthToken, authToken) if err != nil { log.Println("Error deleting session from database") diff --git a/models/user.go b/models/user.go index 7bdfb20..d3739b5 100644 --- a/models/user.go +++ b/models/user.go @@ -49,7 +49,6 @@ func GetCurrentUser(app *app.App, r *http.Request) (User, error) { func GetUserById(app *app.App, id int64) (User, error) { user := User{} - // Query row by id err := app.Db.QueryRow(selectUserById, id).Scan(&user.Id, &user.Username, &user.Password, &user.CreatedAt, &user.UpdatedAt) if err != nil { log.Println("Get user error (user not found) for user id:" + strconv.FormatInt(id, 10)) @@ -63,7 +62,6 @@ func GetUserById(app *app.App, id int64) (User, error) { func GetUserByUsername(app *app.App, username string) (User, error) { user := User{} - // Query row by username err := app.Db.QueryRow(selectUserByUsername, username).Scan(&user.Id, &user.Username, &user.Password, &user.CreatedAt, &user.UpdatedAt) if err != nil { log.Println("Get user error (user not found) for user:" + username) @@ -75,7 +73,6 @@ func GetUserByUsername(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) { - // Hash password hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { log.Println("Error hashing password when creating user") @@ -97,14 +94,12 @@ func CreateUser(app *app.App, username string, password string, createdAt time.T func AuthenticateUser(app *app.App, w http.ResponseWriter, username string, password string, remember bool) (Session, error) { var user User - // Query row by username err := app.Db.QueryRow(selectUserByUsername, username).Scan(&user.Id, &user.Username, &user.Password, &user.CreatedAt, &user.UpdatedAt) if err != nil { log.Println("Authentication error (user not found) for user:" + username) return Session{}, err } - // Validate password err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) if err != nil { // Failed to validate password, doesn't match log.Println("Authentication error (incorrect password) for user:" + username) @@ -116,14 +111,12 @@ 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) { - // Get cookie from request cookie, err := r.Cookie("session") if err != nil { log.Println("Error getting cookie from request") return } - // Set token to empty string err = DeleteSessionByAuthToken(app, w, cookie.Value) if err != nil { log.Println("Error deleting session by AuthToken") diff --git a/routes/getRoutes.go b/routes/get.go similarity index 84% rename from routes/getRoutes.go rename to routes/get.go index f12596f..e3049b1 100644 --- a/routes/getRoutes.go +++ b/routes/get.go @@ -8,10 +8,10 @@ import ( "net/http" ) -// GetRoutes defines all project get routes -func GetRoutes(app *app.App) { +// Get defines all project get routes +func Get(app *app.App) { // Get controller struct initialize - getController := controllers.GetController{ + getController := controllers.Get{ App: app, } diff --git a/routes/postRoutes.go b/routes/post.go similarity index 72% rename from routes/postRoutes.go rename to routes/post.go index a0d93b1..ebda5d1 100644 --- a/routes/postRoutes.go +++ b/routes/post.go @@ -7,10 +7,10 @@ import ( "net/http" ) -// PostRoutes defines all project post routes -func PostRoutes(app *app.App) { +// Post defines all project post routes +func Post(app *app.App) { // Post controller struct initialize - postController := controllers.PostController{ + postController := controllers.Post{ App: app, } diff --git a/security/csrf.go b/security/csrf.go index 4395298..cd6db3b 100644 --- a/security/csrf.go +++ b/security/csrf.go @@ -10,7 +10,6 @@ import ( // GenerateCsrfToken generates a csrf token and assigns it to a cookie for double submit cookie csrf protection func GenerateCsrfToken(w http.ResponseWriter, _ *http.Request) (string, error) { - // Generate random 64 character string (alpha-numeric) buff := make([]byte, int(math.Ceil(float64(64)/2))) _, err := rand.Read(buff) if err != nil {