package main import ( "encoding/base64" "net/http" "github.com/gin-gonic/gin" ) func declareAPIRoutes(router *gin.Engine) { apiRoutes := router.Group("/api") apiRoutes.Use(authMiddleware()) declareAPIAuthRoutes(apiRoutes) declareAPISurveysRoutes(apiRoutes) declareAPIWorksRoutes(apiRoutes) authRoutes := router.Group("") authRoutes.Use(authMiddleware(loggedUser)) adminRoutes := router.Group("") adminRoutes.Use(authMiddleware(adminRestricted)) initializeGitLabOIDC(router, authRoutes, adminRoutes) apiAuthRoutes := router.Group("/api") apiAuthRoutes.Use(authMiddleware(loggedUser)) declareAPIAuthAsksRoutes(apiAuthRoutes) declareAPIAuthQuestionsRoutes(apiAuthRoutes) declareAPIAuthHelpRoutes(apiAuthRoutes) declareAPIAuthKeysRoutes(apiAuthRoutes) declareAPIAuthSurveysRoutes(apiAuthRoutes) declareAPIAuthUsersRoutes(apiAuthRoutes) declareAPIAuthWorksRoutes(apiAuthRoutes) apiAdminRoutes := router.Group("/api") apiAdminRoutes.Use(authMiddleware(adminRestricted)) apiAdminRoutes.DELETE("/cache", func(c *gin.Context) { _surveys_cache_mutex.Lock() _surveys_cache = map[int64]*Survey{} _surveys_cache_mutex.Unlock() _questions_cache_mutex.Lock() _questions_cache = map[int64]*Question{} _questions_cache_mutex.Unlock() }) declareAPIAdminAsksRoutes(apiAdminRoutes) declareAPIAuthGradesRoutes(apiAdminRoutes) declareAPIAdminHelpRoutes(apiAdminRoutes) declareAPIAdminQuestionsRoutes(apiAdminRoutes) declareAPIAuthRepositoriesRoutes(apiAdminRoutes) declareAPIAdminSurveysRoutes(apiAdminRoutes) declareAPIAdminUsersRoutes(apiAdminRoutes) declareAPIAdminWorksRoutes(apiAdminRoutes) } func loggedUser(u *User, c *gin.Context) bool { if u != nil { return true } c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Permission Denied"}) return false } func adminRestricted(u *User, c *gin.Context) bool { if u != nil && u.IsAdmin { return true } c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Permission Denied"}) return false } func authMiddleware(access ...func(*User, *gin.Context) bool) gin.HandlerFunc { return func(c *gin.Context) { var user *User = nil var session *Session = nil if cookie, err := c.Request.Cookie("auth"); err == nil { if sessionid, err := base64.StdEncoding.DecodeString(cookie.Value); err != nil { eraseCookie(c) c.AbortWithStatusJSON(http.StatusNotAcceptable, gin.H{"errmsg": err.Error()}) return } else if session, err = getSession(sessionid); err != nil { eraseCookie(c) c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"errmsg": err.Error()}) return } else if session.IdUser == nil { user = nil } else if std, err := getUser(int(*session.IdUser)); err != nil { eraseCookie(c) c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"errmsg": err.Error()}) return } else { user = std } } // Check access limitation for _, a := range access { if !a(user, c) { return } } // Retrieve corresponding user c.Set("Session", session) c.Set("LoggedUser", user) // We are now ready to continue c.Next() // On return, check if the session has changed if session != nil && session.HasChanged() { session.Update() } } }