Can update session information from interface and create new ones

This commit is contained in:
nemunaire 2024-05-22 19:47:53 +02:00
parent f0c24ea80e
commit 60d296bcff
2 changed files with 116 additions and 2 deletions

View File

@ -29,6 +29,7 @@ import (
"net/http"
"strconv"
"strings"
"time"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
@ -36,6 +37,7 @@ import (
"git.happydns.org/happyDomain/actions"
"git.happydns.org/happyDomain/config"
"git.happydns.org/happyDomain/internal/session"
"git.happydns.org/happyDomain/model"
"git.happydns.org/happyDomain/storage"
)
@ -60,7 +62,9 @@ func declareUsersAuthRoutes(opts *config.Options, router *gin.RouterGroup) {
router.DELETE("/session", clearSession)
router.GET("/sessions", getSessions)
router.POST("/sessions", createSession)
apiSessionsRoutes := router.Group("/session/:sid")
apiSessionsRoutes.PUT("", updateSession)
apiSessionsRoutes.DELETE("", deleteSession)
apiUserRoutes := router.Group("/users/:uid")
@ -786,6 +790,94 @@ func getSessions(c *gin.Context) {
c.JSON(http.StatusOK, s)
}
// createSession create a new session for the current user
//
// @Summary Create a new session for the current user.
// @Schemes
// @Description Create a new session for the current user.
// @Tags users
// @Accept json
// @Produce json
// @Security securitydefinitions.basic
// @Success 200 {object} happydns.Session
// @Failure 401 {object} happydns.Error "Authentication failure"
// @Router /sessions [post]
func createSession(c *gin.Context) {
var us happydns.Session
err := c.ShouldBindJSON(&us)
if err != nil {
log.Printf("%s sends invalid Session JSON: %s", c.ClientIP(), err.Error())
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
return
}
myuser := c.MustGet("LoggedUser").(*happydns.User)
sessid := session.NewSessionId()
mysession := &happydns.Session{
Id: sessid,
IdUser: myuser.Id,
Description: us.Description,
IssuedAt: time.Now(),
ExpiresOn: time.Now().Add(24 * 365 * time.Hour),
}
err = storage.MainStore.UpdateSession(mysession)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"id": sessid})
}
// updateSession update a session owned by the current user
//
// @Summary Update a session owned by the current user.
// @Schemes
// @Description Update a session owned by the current user.
// @Tags users
// @Accept json
// @Param sessionId path string true "Session identifier"
// @Produce json
// @Security securitydefinitions.basic
// @Success 200 {object} happydns.Session
// @Failure 401 {object} happydns.Error "Authentication failure"
// @Router /sessions/{sessionId} [put]
func updateSession(c *gin.Context) {
var us happydns.Session
err := c.ShouldBindJSON(&us)
if err != nil {
log.Printf("%s sends invalid Session JSON: %s", c.ClientIP(), err.Error())
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": fmt.Sprintf("Something is wrong in received data: %s", err.Error())})
return
}
myuser := c.MustGet("LoggedUser").(*happydns.User)
s, err := storage.MainStore.GetSession(c.Param("sid"))
if err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": err.Error()})
return
}
if !myuser.Id.Equals(s.IdUser) {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "You are not allowed to update this session."})
return
}
s.Description = us.Description
s.ExpiresOn = us.ExpiresOn
err = storage.MainStore.UpdateSession(s)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
return
}
c.JSON(http.StatusOK, s)
}
// deleteSession delete a session owned by the current user
//
// @Summary Delete a session owned by the current user.

View File

@ -107,7 +107,7 @@ func (s *SessionStore) Save(r *http.Request, w http.ResponseWriter, session *ses
s.storage.DeleteSession(session.ID)
} else {
if session.ID == "" {
session.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=")
session.ID = NewSessionId()
}
encrypted, err := securecookie.EncodeMulti(session.Name(), session.ID, s.Codecs...)
if err != nil {
@ -145,7 +145,25 @@ func (s *SessionStore) load(session *sessions.Session) error {
return err
}
return securecookie.DecodeMulti(session.Name(), mysession.Content, &session.Values, s.Codecs...)
err = securecookie.DecodeMulti(session.Name(), mysession.Content, &session.Values, s.Codecs...)
if err != nil {
return err
}
if len(mysession.IdUser) > 0 {
session.Values["iduser"] = []byte(mysession.IdUser)
}
if len(mysession.Description) > 0 {
session.Values["description"] = mysession.Description
}
if _, ok := session.Values["created_on"].(time.Time); !ok && !mysession.IssuedAt.IsZero() {
session.Values["created_on"] = mysession.IssuedAt
}
if !mysession.ExpiresOn.IsZero() {
session.Values["expires_on"] = mysession.ExpiresOn
}
return nil
}
// save writes encoded session.Values to a database record.
@ -200,3 +218,7 @@ func (s *SessionStore) save(session *sessions.Session, ua string) error {
return s.storage.UpdateSession(mysession)
}
func NewSessionId() string {
return strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(64)), "=")
}