func (u *users) Authorize(c *gin.Context) { var user model.User db := database.GetDB() if err := c.Bind(&user); err != nil { c.AbortWithError(http.StatusBadRequest, err) } else { if id, err := user.Auth(db); err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Password or email incorrect")) } else if u, err := url.Parse(c.Request.Referer()); err != nil { c.AbortWithError(http.StatusBadRequest, err) } else { s := session.GetSession(c.Request) s.Values["user_id"] = id session.Save(c.Request, c.Writer) q := u.Query() if err := db.Model(&user).Preload("Role").Preload("Organization").First(&user, id).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else if q.Get("response_type") != "code" || q.Get("client_id") == "" || q.Get("redirect_uri") == "" { c.AbortWithError(http.StatusBadRequest, errors.New("Unsupported request")) } else { params := url.Values{} params.Add("response_type", q.Get("response_type")) params.Add("client_id", q.Get("client_id")) params.Add("redirect_uri", q.Get("redirect_uri")) params.Add("scope", q.Get("scope")) c.Redirect(http.StatusFound, "/auth?"+params.Encode()) } } } }
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) migrate() router := gin.Default() router.Use(errorHandler()) router.Use(panicHandler()) // templates router.LoadHTMLGlob("templates/*") router.GET("/login", controller.Users.Login) router.GET("/logout", controller.Users.Logout) router.POST("/login", controller.Users.Authorize) router.GET("/auth", controller.OAuth2.Auth) router.POST("/token", controller.OAuth2.Token) revyapp := router.Group("/revy") revyapp.GET("/callback", controller.Revy.Callback) api := router.Group("/", validateToken()) api.GET("/users/me", controller.Users.Me) api.GET("/smells", todo) api.GET("/statuses", todo) api.GET("/repos", controller.Repos.List) api.POST("/repos", controller.Repos.Create) api.GET("/repos/:repo_id", findRepo(), controller.Repos.Show) api.PATCH("/repos/:repo_id", findRepo(), controller.Repos.Update) api.DELETE("/repos/:repo_id", findRepo(), controller.Repos.Delete) reposApi := api.Group("/repos/:repo_id", findRepo()) { reposApi.GET("/reviews", controller.Reviews.List) reposApi.POST("/reviews", controller.Reviews.Create) reposApi.GET("/reviews/:review_id", controller.Reviews.Show) reposApi.PATCH("/reviews/:review_id", findReview(), controller.Reviews.Update) reposApi.DELETE("/reviews/:review_id", findReview(), controller.Reviews.Delete) } reviewsApi := reposApi.Group("/reviews/:review_id", findReview()) { reviewsApi.GET("/comments", controller.Comments.List) reviewsApi.POST("/comments", controller.Comments.Create) reviewsApi.GET("/comments/:comment_id", todo) reviewsApi.PUT("/comments/:comment_id", todo) reviewsApi.DELETE("/comments/:comment_id", todo) } log.Fatal(http.ListenAndServe(":"+port(), router)) database.GetDB().Close() database.GetRedisPool().Close() }
// DELETE /repos/:repo_id/reviews/:review_id func (r *reviews) Delete(c *gin.Context) { review := c.MustGet("review").(model.Review) db := database.GetDB() if err := db.Delete(&review).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.String(http.StatusNoContent, "") } }
// GET /repos/:repo_id/reviews/:review_id/comments func (r *comments) List(c *gin.Context) { var comments []model.Comment review := c.MustGet("review").(model.Review) db := database.GetDB() if err := db.Where(model.Comment{ReviewId: review.ID}).Preload("User").Find(&comments).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.JSON(http.StatusOK, comments) } }
// GET /repos func (r *repos) List(c *gin.Context) { var repos []model.Repository user := c.MustGet("user").(model.User) db := database.GetDB() if err := db.Where(&model.Repository{OrganizationId: user.OrganizationId}).Find(&repos).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.JSON(http.StatusOK, repos) } }
// GET /repos/:repo_id/reviews/:review_id func (r *reviews) Show(c *gin.Context) { var review model.Review review_id := c.Param("review_id") repo := c.MustGet("repo").(model.Repository) db := database.GetDB() if err := db.Where(&model.Review{RepositoryId: repo.ID}).Preload("Smell").Preload("Status").Preload("Comments.User").First(&review, review_id).Error; err != nil { c.AbortWithError(http.StatusNotFound, err) } else { c.JSON(http.StatusOK, review) } }
// POST /repos func (r *repos) Create(c *gin.Context) { var repo model.Repository user := c.MustGet("user").(model.User) db := database.GetDB() if c.Bind(&repo) == nil { repo.OrganizationId = user.OrganizationId if err := db.Create(&repo).Error; err != nil { c.AbortWithError(http.StatusConflict, errors.New("uuid already taken")) } else { c.JSON(http.StatusCreated, repo) } } }
func GetCurrentUser(req *http.Request) model.User { var user model.User id := GetSession(req).Values["user_id"] if id != nil { db := database.GetDB() db.First(&user, id) } else { user = model.User{} } return user }
func findReview() gin.HandlerFunc { return func(c *gin.Context) { var review model.Review repo := c.MustGet("repo").(model.Repository) review_id := c.Param("review_id") db := database.GetDB() if err := db.Where(&model.Review{RepositoryId: repo.ID}).First(&review, review_id).Error; err != nil { c.AbortWithError(http.StatusNotFound, err) } else { c.Set("review", review) c.Next() } } }
func migrate() { db := database.GetDB() db.AutoMigrate( &model.Comment{}, &model.Organization{}, &model.Repository{}, &model.Review{}, &model.Role{}, &model.Smell{}, &model.Status{}, &model.User{}, &model.Application{}, &model.AccessToken{}) }
func findRepo() gin.HandlerFunc { return func(c *gin.Context) { var repo model.Repository repo_id := c.Param("repo_id") user := c.MustGet("user").(model.User) db := database.GetDB() if err := db.Where(&model.Repository{OrganizationId: user.OrganizationId}).First(&repo, repo_id).Error; err != nil { c.AbortWithError(http.StatusNotFound, err) } else { c.Set("repo", repo) c.Next() } } }
// PATCH /repos/:repo_id/reviews/:review_id func (r *reviews) Update(c *gin.Context) { type updateParams struct { Smell string `json:"smell"` Status string `json:"status"` AssignedTo uint `json:"assigned_to"` } var params updateParams review := c.MustGet("review").(model.Review) db := database.GetDB() if c.Bind(¶ms) == nil { updates := model.Review{} if params.Smell != "" { var smell model.Smell if err := db.Where("name = ?", params.Smell).Find(&smell).Error; err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Invalid smell")) } updates.SmellId = smell.ID } if params.Status != "" { var status model.Status if err := db.Where("name = ?", params.Status).Find(&status).Error; err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Invalid status")) } updates.StatusId = status.ID } if params.AssignedTo > 0 { updates.AssignedToId = params.AssignedTo } if c.IsAborted() { return } else if updates.SmellId == 0 && updates.StatusId == 0 && updates.AssignedToId == 0 { c.String(http.StatusNotModified, "") } else { if err := db.Model(&review).Updates(updates).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.String(http.StatusNoContent, "") } } } }
// GET /repos/:repo_id/reviews func (r *reviews) List(c *gin.Context) { var reviews []model.Review var query queryParam repo := c.MustGet("repo").(model.Repository) db := database.GetDB() if c.Bind(&query) == nil { if query.Limit > limitMax { c.AbortWithError(http.StatusBadRequest, errors.New("limit should be less than "+strconv.Itoa(limitMax))) } q := db.Where(&model.Review{RepositoryId: repo.ID}).Preload("Smell").Preload("Status") if query.Limit > 0 { q = q.Limit(query.Limit) } if query.SinceId > 0 { q = q.Where("reviews.id >= ?", query.SinceId) } if query.Smell != "" { var smell model.Smell if err := db.Where("name = ?", query.Smell).Find(&smell).Error; err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Invalid smell")) } q = q.Where("smell_id = ?", smell.ID) } if query.Status != "" { var status model.Status if err := db.Where("name = ?", query.Status).Find(&status).Error; err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Invalid status")) } q = q.Where("status_id = ?", status.ID) } if c.IsAborted() { return } if err := q.Find(&reviews).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.JSON(http.StatusOK, reviews) } } }
// POST /repos/:repo_id/reviews func (r *reviews) Create(c *gin.Context) { var params createParam user := c.MustGet("user").(model.User) repo := c.MustGet("repo").(model.Repository) db := database.GetDB() if c.Bind(¶ms) == nil { review := model.Review{} if params.Smell == "" { params.Smell = smellDefault } var smell model.Smell var status model.Status review.RepositoryId = repo.ID review.CreatedById = user.ID review.Sha = params.Sha review.File = params.File review.Line = params.Line review.AssignedToId = params.AssignedToId if err := db.Where("name = ?", params.Smell).Find(&smell).Error; err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Invalid smell")) } else { review.SmellId = smell.ID review.Smell = smell } if err := db.Where("name = ?", statusDefault).Find(&status).Error; err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Invalid status")) } else { review.StatusId = status.ID review.Status = status } if c.IsAborted() { return } if err := db.Create(&review).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.JSON(http.StatusCreated, review) } } }
func validateToken() gin.HandlerFunc { return func(c *gin.Context) { var at model.AccessToken authorization := c.Request.Header.Get("Authorization") token := strings.Replace(authorization, "Bearer ", "", 1) db := database.GetDB() if authorization == "" { c.AbortWithError(http.StatusBadRequest, errors.New("Authorization header required")) } else if err := db.Where(&model.AccessToken{AccessToken: token}).Where("expired_at > NOW()").Preload("User").First(&at).Error; err != nil { c.AbortWithError(http.StatusBadRequest, errors.New("Invalid access token")) } else { c.Set("user", at.User) c.Next() } } }
// PATCH /repos/:repo_id func (r *repos) Update(c *gin.Context) { type updateParams struct { Name string `json:"name" binding:"required"` } var params updateParams repo := c.MustGet("repo").(model.Repository) db := database.GetDB() if c.Bind(¶ms) == nil { if err := db.Model(&repo).Updates(map[string]interface{}{"name": params.Name}).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.String(http.StatusNoContent, "") } } }
// POST /repos/:repo_id/reviews/:review_id/comments func (r *comments) Create(c *gin.Context) { var params createParams user := c.MustGet("user").(model.User) review := c.MustGet("review").(model.Review) db := database.GetDB() if c.Bind(¶ms) == nil { comment := model.Comment{ ReviewId: review.ID, UserId: user.ID, Content: params.Content, } if err := db.Create(&comment).Preload("User").First(&comment, comment.ID).Error; err != nil { c.AbortWithError(http.StatusInternalServerError, err) } else { c.JSON(http.StatusCreated, comment) } } }