Refactor permissions checks to avoid questions/works leaks between promotions/groups/start-availability
Thanks-To François Dautrême <francois.dautreme@epita.fr>
This commit is contained in:
parent
bf5b0e88dd
commit
f675047ce8
3 changed files with 57 additions and 53 deletions
46
works.go
46
works.go
|
@ -43,7 +43,11 @@ func declareAPIWorksRoutes(router *gin.RouterGroup) {
|
|||
} else {
|
||||
for _, w := range works {
|
||||
if w.Group == "" || strings.Contains(u.Groups, ","+w.Group+",") {
|
||||
// Remove informations not needed on front page for students
|
||||
w.Promo = 0
|
||||
w.Group = ""
|
||||
w.DescriptionRaw = ""
|
||||
|
||||
response = append(response, w)
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +83,10 @@ func declareAPIWorksRoutes(router *gin.RouterGroup) {
|
|||
} else {
|
||||
for _, w := range works {
|
||||
if w.Group == "" || strings.Contains(u.Groups, ","+w.Group+",") {
|
||||
// Remove informations not needed on front page for students
|
||||
w.Promo = 0
|
||||
w.Group = ""
|
||||
|
||||
response = append(response, w)
|
||||
}
|
||||
}
|
||||
|
@ -193,16 +200,7 @@ func declareAPIAuthWorksRoutes(router *gin.RouterGroup) {
|
|||
worksRoutes.Use(workUserAccessHandler)
|
||||
|
||||
worksRoutes.GET("", func(c *gin.Context) {
|
||||
u := c.MustGet("LoggedUser").(*User)
|
||||
w := c.MustGet("work").(*Work)
|
||||
|
||||
if u.IsAdmin {
|
||||
c.JSON(http.StatusOK, w)
|
||||
} else if w.Shown && w.StartAvailability.Before(time.Now()) && (w.Group == "" || strings.Contains(u.Groups, ","+w.Group+",")) {
|
||||
c.JSON(http.StatusOK, w)
|
||||
} else {
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Permission denied"})
|
||||
}
|
||||
c.JSON(http.StatusOK, c.MustGet("work").(*Work))
|
||||
})
|
||||
|
||||
// Grades related to works
|
||||
|
@ -239,18 +237,24 @@ func workHandler(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (w *Work) checkUserAccessToWork(u *User) bool {
|
||||
return u.IsAdmin || (u.Promo == w.Promo && w.Shown && (w.Group == "" || strings.Contains(u.Groups, ","+w.Group+",")))
|
||||
}
|
||||
|
||||
func workUserAccessHandler(c *gin.Context) {
|
||||
u := c.MustGet("LoggedUser").(*User)
|
||||
w := c.MustGet("work").(*Work)
|
||||
|
||||
if u.IsAdmin {
|
||||
c.Next()
|
||||
} else if w.Shown && (w.Group == "" || strings.Contains(u.Groups, ","+w.Group+",")) {
|
||||
c.Next()
|
||||
} else {
|
||||
if !w.checkUserAccessToWork(u) {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Work not found."})
|
||||
return
|
||||
}
|
||||
if !u.IsAdmin && w.StartAvailability.After(time.Now()) {
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not accessible yet"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
type OneWork struct {
|
||||
|
@ -291,14 +295,14 @@ func allWorks(cnd string, param ...interface{}) (items []*OneWork, err error) {
|
|||
type Work struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Promo uint `json:"promo"`
|
||||
Group string `json:"group"`
|
||||
Promo uint `json:"promo,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
Shown bool `json:"shown"`
|
||||
Description string `json:"description"`
|
||||
Description string `json:"description,omitempty"`
|
||||
DescriptionRaw string `json:"descr_raw,omitempty"`
|
||||
Tag string `json:"tag"`
|
||||
SubmissionURL *string `json:"submission_url"`
|
||||
Corrected bool `json:"corrected"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
SubmissionURL *string `json:"submission_url,omitempty"`
|
||||
Corrected bool `json:"corrected,omitempty"`
|
||||
StartAvailability time.Time `json:"start_availability"`
|
||||
EndAvailability time.Time `json:"end_availability"`
|
||||
}
|
||||
|
|
Reference in a new issue