This repository has been archived on 2024-03-28. You can view files and clone it, but cannot push or open issues or pull requests.
atsebay.t/auth.go

166 lines
3.8 KiB
Go
Raw Normal View History

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
)
var LocalAuthFunc = checkAuthKrb5
var allowLocalAuth bool
var localAuthUsers arrayFlags
var mainBanner string
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{
User: newuser,
CurrentPromo: currentPromo,
MessageBanner: mainBanner,
2022-09-10 23:05:51 +00:00
})
})
}
type authToken struct {
*User
CurrentPromo uint `json:"current_promo"`
Groups []string `json:"groups"`
MessageBanner string `json:"banner,omitempty"`
}
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 {
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
}
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) {
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
}
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
upd_user = true
2021-11-18 11:12:28 +00:00
}
2021-09-15 22:26:09 +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
}
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 {
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
}