Example #1
0
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())
			}
		}
	}
}
Example #2
0
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()
}
Example #3
0
// 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, "")
	}
}
Example #4
0
// 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)
	}
}
Example #5
0
// 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)
	}
}
Example #6
0
// 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)
	}
}
Example #7
0
// 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)
		}
	}
}
Example #8
0
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
}
Example #9
0
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()
		}
	}
}
Example #10
0
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{})
}
Example #11
0
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()
		}
	}
}
Example #12
0
// 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(&params) == 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, "")
			}
		}
	}
}
Example #13
0
// 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)
		}
	}
}
Example #14
0
// 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(&params) == 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)
		}
	}
}
Example #15
0
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()
		}
	}
}
Example #16
0
// 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(&params) == 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, "")
		}
	}
}
Example #17
0
// 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(&params) == 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)
		}
	}
}