2020-03-04 11:07:12 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/base64"
|
|
|
|
"net/http"
|
2022-08-02 09:41:13 +00:00
|
|
|
"strings"
|
2020-03-04 11:07:12 +00:00
|
|
|
"time"
|
2022-08-02 09:41:13 +00:00
|
|
|
"unicode"
|
2020-03-04 11:07:12 +00:00
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
2020-03-04 11:07:12 +00:00
|
|
|
)
|
|
|
|
|
2021-09-22 15:02:30 +00:00
|
|
|
var LocalAuthFunc = checkAuthKrb5
|
2022-09-07 12:08:23 +00:00
|
|
|
var allowLocalAuth bool
|
2021-09-22 15:02:30 +00:00
|
|
|
var localAuthUsers arrayFlags
|
2023-03-07 01:53:47 +00:00
|
|
|
var mainBanner string
|
2021-09-22 15:02:30 +00:00
|
|
|
|
|
|
|
type loginForm struct {
|
|
|
|
Login string `json:"username"`
|
|
|
|
Password string `json:"password"`
|
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
func declareAPIAuthRoutes(router *gin.RouterGroup) {
|
|
|
|
router.GET("/auth", validateAuthToken)
|
|
|
|
router.POST("/auth", func(c *gin.Context) {
|
|
|
|
LocalAuthFunc(c)
|
|
|
|
})
|
|
|
|
router.POST("/auth/logout", logout)
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2022-09-10 23:05:51 +00:00
|
|
|
func declareAPIAdminAuthRoutes(router *gin.RouterGroup) {
|
|
|
|
router.POST("/auth/impersonate", func(c *gin.Context) {
|
|
|
|
session := c.MustGet("Session").(*Session)
|
|
|
|
|
|
|
|
var u *User
|
|
|
|
if err := c.ShouldBindJSON(&u); err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
newuser, err := getUser(int(u.Id))
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
session.IdUser = &newuser.Id
|
|
|
|
session.Update()
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, authToken{
|
2023-03-07 01:53:47 +00:00
|
|
|
User: newuser,
|
|
|
|
CurrentPromo: currentPromo,
|
|
|
|
MessageBanner: mainBanner,
|
2022-09-10 23:05:51 +00:00
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-02-21 08:21:30 +00:00
|
|
|
type authToken struct {
|
|
|
|
*User
|
2023-03-07 01:53:47 +00:00
|
|
|
CurrentPromo uint `json:"current_promo"`
|
|
|
|
Groups []string `json:"groups"`
|
|
|
|
MessageBanner string `json:"banner,omitempty"`
|
2022-02-21 08:21:30 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
func validateAuthToken(c *gin.Context) {
|
|
|
|
if u, ok := c.Get("LoggedUser"); !ok || u.(*User) == nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"errmsg": "Not connected"})
|
|
|
|
return
|
2021-11-18 11:12:28 +00:00
|
|
|
} else {
|
2023-03-07 01:53:47 +00:00
|
|
|
t := authToken{User: u.(*User), CurrentPromo: currentPromo, MessageBanner: mainBanner}
|
2022-08-02 09:41:13 +00:00
|
|
|
|
|
|
|
t.Groups = strings.Split(strings.TrimFunc(t.User.Groups, func(r rune) bool { return !unicode.IsLetter(r) }), ",")
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, t)
|
2021-11-18 11:12:28 +00:00
|
|
|
}
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
func logout(c *gin.Context) {
|
|
|
|
eraseCookie(c)
|
|
|
|
c.JSON(http.StatusOK, true)
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2022-11-11 10:14:43 +00:00
|
|
|
func completeAuth(c *gin.Context, username string, email string, firstname string, lastname string, promo uint, groups string, session *Session) (usr *User, err error) {
|
2020-03-04 11:07:12 +00:00
|
|
|
if !userExists(username) {
|
2022-11-11 10:14:43 +00:00
|
|
|
if promo == 0 {
|
|
|
|
promo = currentPromo
|
|
|
|
}
|
|
|
|
if usr, err = NewUser(username, email, firstname, lastname, promo, groups); err != nil {
|
2021-11-18 11:12:28 +00:00
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
} else if usr, err = getUserByLogin(username); err != nil {
|
2021-11-18 11:12:28 +00:00
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2022-11-11 10:14:43 +00:00
|
|
|
upd_user := false
|
|
|
|
|
|
|
|
// Update user's promo if it has changed
|
|
|
|
if promo != 0 && promo != usr.Promo {
|
|
|
|
usr.Promo = promo
|
|
|
|
upd_user = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update user's group if they have been modified
|
2021-11-18 11:12:28 +00:00
|
|
|
if len(groups) > 0 {
|
|
|
|
if len(groups) > 255 {
|
|
|
|
groups = groups[:255]
|
|
|
|
}
|
|
|
|
if usr.Groups != groups {
|
|
|
|
usr.Groups = groups
|
2022-11-11 10:14:43 +00:00
|
|
|
upd_user = true
|
2021-11-18 11:12:28 +00:00
|
|
|
}
|
2021-09-15 22:26:09 +00:00
|
|
|
}
|
|
|
|
|
2022-11-11 10:14:43 +00:00
|
|
|
if upd_user {
|
|
|
|
usr.Update()
|
|
|
|
}
|
|
|
|
|
2020-03-04 11:07:12 +00:00
|
|
|
if session == nil {
|
2022-07-09 17:42:00 +00:00
|
|
|
session, err = usr.NewSession()
|
2020-03-04 11:07:12 +00:00
|
|
|
} else {
|
|
|
|
_, err = session.SetUser(usr)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
2021-11-18 11:12:28 +00:00
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
http.SetCookie(c.Writer, &http.Cookie{
|
2020-09-13 14:36:07 +00:00
|
|
|
Name: "auth",
|
|
|
|
Value: base64.StdEncoding.EncodeToString(session.Id),
|
|
|
|
Path: baseURL + "/",
|
|
|
|
Expires: time.Now().Add(30 * 24 * time.Hour),
|
2020-03-04 11:07:12 +00:00
|
|
|
HttpOnly: true,
|
2020-09-13 14:36:07 +00:00
|
|
|
SameSite: http.SameSiteStrictMode,
|
2022-05-15 10:35:03 +00:00
|
|
|
Secure: true,
|
2020-03-04 11:07:12 +00:00
|
|
|
})
|
|
|
|
|
2021-11-18 11:12:28 +00:00
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 17:42:00 +00:00
|
|
|
func eraseCookie(c *gin.Context) {
|
|
|
|
http.SetCookie(c.Writer, &http.Cookie{
|
|
|
|
Name: "auth",
|
|
|
|
Value: "",
|
|
|
|
Path: baseURL + "/",
|
|
|
|
Expires: time.Unix(0, 0),
|
|
|
|
HttpOnly: true,
|
|
|
|
SameSite: http.SameSiteStrictMode,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func dummyAuth(c *gin.Context) {
|
2020-03-04 11:07:12 +00:00
|
|
|
var lf map[string]string
|
2022-07-09 17:42:00 +00:00
|
|
|
if err := c.ShouldBindJSON(&lf); err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|
|
|
|
|
2022-11-11 10:14:43 +00:00
|
|
|
if usr, err := completeAuth(c, lf["username"], lf["email"], lf["firstname"], lf["lastname"], currentPromo, "", nil); err != nil {
|
2022-07-09 17:42:00 +00:00
|
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
} else {
|
2023-03-07 01:53:47 +00:00
|
|
|
c.JSON(http.StatusOK, authToken{User: usr, CurrentPromo: currentPromo, MessageBanner: mainBanner})
|
2022-07-09 17:42:00 +00:00
|
|
|
}
|
2020-03-04 11:07:12 +00:00
|
|
|
}
|