package main import ( "errors" "fmt" "log" "net/http" . "planner/errors" "planner/models" . "planner/models" "github.com/gin-gonic/gin" _ "github.com/mattn/go-sqlite3" ) func main() { fmt.Println("Opening database db.sqlite") orm := bootstrapDatabase() if orm == nil { log.Fatal("Failed to init database") return } db, _ := orm.DB() defer db.Close() r := gin.Default() r.GET("/", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "pong", }) }) r.POST("/login", func(c *gin.Context) { var q struct { Username string `json:"username" form:"username"` Password string `json:"password" form:"password"` } if c.ShouldBind(&q) == nil { if q.Username == "" { c.String(http.StatusBadRequest, "Login data is null") } else { user := User{ Username: q.Username, } orm.Take(&user) if user.Password == q.Password { c.JSON(http.StatusOK, map[string]string{"username": user.Username}) } else { c.Status(http.StatusForbidden) } } } else { c.String(http.StatusBadRequest, "Unable to bind data") } }) r.GET("/users", func(c *gin.Context) { var q struct { Name string `form:"name"` } if c.ShouldBind(&q) == nil { user := User{ Username: q.Name, } orm.Take(&user) fmt.Println(user) c.JSON(http.StatusOK, user) } }) r.POST("/users", func(c *gin.Context) { var u User if c.ShouldBind(&u) == nil { orm.Create(&u) c.Status(http.StatusCreated) } else { fmt.Print("Could not bind model") } }) r.POST("/plans", func(c *gin.Context) { username, _, ok := c.Request.BasicAuth() if !ok { c.Status(http.StatusUnauthorized) return } u := User{ Username: username, } if result := orm.Take(&u); result.Error != nil { c.String(http.StatusNotFound, "Unable to find user "+username) return } var plan_req struct { Name string `json:"name"` } c.Bind(&plan_req) var plan Plan = Plan{ Name: plan_req.Name, Owner: u.Username, Members: []Member{ {UserID: u.Username}, }, } result := orm.Create(&plan) if result.Error != nil { c.JSON(http.StatusInternalServerError, result.Error) } else { c.JSON(http.StatusOK, plan_req) } }) r.GET("/plans", func(c *gin.Context) { u := extract_user(orm, c) if u == nil { return } plans, err := u.GetPlans(orm) if err == nil { c.JSON(http.StatusOK, plans) } else { c.String(http.StatusInternalServerError, err.Error()) } }) r.GET("/plans/:id", func(c *gin.Context) { user := extract_user(orm, c) if user == nil { return } var params struct { Id uint `uri:"id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { return } plan, err := GetPlan(orm, *user, params.Id) if err == nil { c.JSON(http.StatusOK, plan) } else if errors.Is(err, ErrNotMember) { c.Status(http.StatusForbidden) } else if errors.Is(err, ErrNotFound) { c.Status(http.StatusNotFound) } else { c.String(http.StatusInternalServerError, err.Error()) } }) r.POST("/plans/:id/polls", func(c *gin.Context) { user := extract_user(orm, c) if user == nil { return } var params struct { Id uint `uri:"id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { return } plan, err := GetPlan(orm, *user, params.Id) if errors.Is(err, ErrNotFound) { c.Status(http.StatusNotFound) return } else if errors.Is(err, ErrNotMember) { c.Status(http.StatusForbidden) return } else if err != nil { c.String(http.StatusInternalServerError, err.Error()) return } var poll_opts struct { Options string `json:"options"` } bind_result = c.Bind(&poll_opts) if bind_result != nil { fmt.Println(bind_result) return } poll := Poll{ PlanID: plan.ID, Options: poll_opts.Options, } orm.Create(&poll) c.JSON(http.StatusCreated, poll) }) r.GET("/plans/:id/polls", func(c *gin.Context) { user := extract_user(orm, c) if user == nil { return } var params struct { Id uint `uri:"id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { c.Status(http.StatusBadRequest) return } var polls []Poll orm.Where("plan_id = ?", params.Id).Find(&polls) c.JSON(http.StatusOK, polls) }) r.GET("/polls/:poll_id", func(c *gin.Context) { user := extract_user(orm, c) if user == nil { return } var params struct { PollId uint `uri:"poll_id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { fmt.Println(bind_result) return } fmt.Println(params) poll, _ := models.GetPoll(orm, *user, params.PollId) c.JSON(http.StatusOK, poll) }) r.GET("/polls/:poll_id/votes", func(c *gin.Context) { user := extract_user(orm, c) if user == nil { return } var params struct { PollId uint `uri:"poll_id"` } bind_result := c.BindUri(¶ms) if bind_result != nil { fmt.Println(bind_result) return } var votes []Vote orm.Where("poll_id = ?", params.PollId).Find(&votes) c.JSON(http.StatusOK, &votes) }) r.POST("/polls/:poll_id/votes", func(c *gin.Context) { user := extract_user(orm, c) if user == nil { return } var path_params struct { PollId uint `uri:"poll_id"` } bind_result := c.BindUri(&path_params) if bind_result != nil { fmt.Println(bind_result) return } poll, err := models.GetPoll(orm, *user, path_params.PollId) if err != nil { c.String(http.StatusInternalServerError, err.Error()) return } var vote_params struct { Vote string `json:"vote"` } c.Bind(&vote_params) if err := poll.SetVote(orm, *user, vote_params.Vote); err != nil { c.String(http.StatusBadRequest, err.Error()) } c.Status(http.StatusOK) }) r.Run() }