package main import ( "log" "net/http" "github.com/gin-gonic/gin" ) func declareAPIAuthGradesRoutes(router *gin.RouterGroup) { router.GET("/grades", func(c *gin.Context) { uauth := c.MustGet("LoggedUser").(*User) if survey, ok := c.Get("survey"); !ok { if uauth == nil || !uauth.IsAdmin { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not authorized"}) return } grades, err := GetAllGrades() if err != nil { log.Println("Unable to GetAllGrades:", err) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "An error occurs when trying to retrieve grades."}) return } c.JSON(http.StatusOK, grades) } else { s := survey.(*Survey) if user, ok := c.Get("user"); ok { u := user.(*User) if uauth == nil || !((s.Shown && u.Id == uauth.Id) || uauth.IsAdmin) { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not accessible"}) return } score, err := s.GetUserGrades(u) if err != nil { log.Printf("Unable to GetUserGrades(sid=%d; uid=%d): %s", s.Id, u.Id, err.Error()) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrive user grade. Please try again later."}) return } if score == nil { c.JSON(http.StatusOK, "N/A") } else { c.JSON(http.StatusOK, score) } } else if uauth.IsAdmin { scores, err := s.GetGrades() if err != nil { log.Printf("Unable to GetGrades(sid=%d): %s", s.Id, err.Error()) c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrive grades."}) return } c.JSON(http.StatusOK, scores) } else { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Not authorized"}) return } } }) } func GetAllGrades() (scores map[int64]map[int64]*float64, err error) { if rows, errr := DBQuery("SELECT id_user, id_survey, SUM(score)/COUNT(*) FROM student_scores GROUP BY id_user, id_survey"); err != nil { return nil, errr } else { defer rows.Close() scores = map[int64]map[int64]*float64{} for rows.Next() { var id_user int64 var id_survey int64 var score *float64 if err = rows.Scan(&id_user, &id_survey, &score); err != nil { return } if scores[id_user] == nil { scores[id_user] = map[int64]*float64{} } scores[id_user][id_survey] = score } if err = rows.Err(); err != nil { return } } return } func (s Survey) GetGrades() (scores map[int64]*float64, err error) { if rows, errr := DBQuery("SELECT id_question, SUM(score)/COUNT(*) FROM student_scores WHERE id_survey=? GROUP BY id_question", s.Id); err != nil { return nil, errr } else { defer rows.Close() scores = map[int64]*float64{} for rows.Next() { var id_question int64 var score *float64 if err = rows.Scan(&id_question, &score); err != nil { return } scores[id_question] = score } if err = rows.Err(); err != nil { return } } return } func (s Survey) GetUserGrades(u *User) (scores map[int64]*float64, err error) { if rows, errr := DBQuery("SELECT id_question, MAX(score) FROM student_scores WHERE id_survey=? AND id_user = ? GROUP BY id_question", s.Id, u.Id); err != nil { return nil, errr } else { defer rows.Close() scores = map[int64]*float64{} for rows.Next() { var id_question int64 var score *float64 if err = rows.Scan(&id_question, &score); err != nil { return } scores[id_question] = score } if err = rows.Err(); err != nil { return } } return }