diff --git a/internal/api/members/controler.go b/internal/api/members/controler.go index a6ed8ca3..1a6d5a4f 100644 --- a/internal/api/members/controler.go +++ b/internal/api/members/controler.go @@ -68,7 +68,7 @@ func (h *MembersHandler) membersCreate(w http.ResponseWriter, r *http.Request) { // TODO: Refactor. // data.ID - session, err := h.sessions.Create(*data.MemberProfile) + session, _, err := h.sessions.Create(*data.MemberProfile) if err != nil { utils.HttpInternalServerError(w, err) return diff --git a/internal/api/session.go b/internal/api/session.go index 446843d8..69761ba0 100644 --- a/internal/api/session.go +++ b/internal/api/session.go @@ -31,7 +31,7 @@ func (api *ApiManagerCtx) Login(w http.ResponseWriter, r *http.Request) { } // TODO: Proper login. - session, err := api.sessions.Create(types.MemberProfile{ + session, token, err := api.sessions.Create(types.MemberProfile{ Name: data.ID, IsAdmin: true, CanLogin: true, @@ -53,7 +53,7 @@ func (api *ApiManagerCtx) Login(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{ Name: "NEKO_SESSION", - Value: session.ID(), + Value: token, Expires: CookieExpirationDate, Secure: !UnsecureCookies, SameSite: sameSite, diff --git a/internal/session/auth.go b/internal/session/auth.go index 3a46dd34..5eb23bdb 100644 --- a/internal/session/auth.go +++ b/internal/session/auth.go @@ -14,7 +14,7 @@ func (manager *SessionManagerCtx) Authenticate(r *http.Request) (types.Session, return nil, fmt.Errorf("no authentication provided") } - session, ok := manager.Get(token) + session, ok := manager.GetByToken(token) if !ok { return nil, fmt.Errorf("session not found") } diff --git a/internal/session/manager.go b/internal/session/manager.go index 66ebf2eb..26f9ed1a 100644 --- a/internal/session/manager.go +++ b/internal/session/manager.go @@ -19,6 +19,7 @@ func New(config *config.Session) *SessionManagerCtx { config: config, host: nil, hostMu: sync.Mutex{}, + tokens: make(map[string]string), sessions: make(map[string]*SessionCtx), sessionsMu: sync.Mutex{}, emmiter: events.New(), @@ -30,36 +31,48 @@ type SessionManagerCtx struct { config *config.Session host types.Session hostMu sync.Mutex + tokens map[string]string sessions map[string]*SessionCtx sessionsMu sync.Mutex emmiter events.EventEmmiter } -func (manager *SessionManagerCtx) Create(profile types.MemberProfile) (types.Session, error) { +func (manager *SessionManagerCtx) Create(profile types.MemberProfile) (types.Session, string, error) { id, err := utils.NewUID(32) if err != nil { - return nil, err + return nil, "", err + } + + token, err := utils.NewUID(64) + if err != nil { + return nil, "", err } manager.sessionsMu.Lock() - _, ok := manager.sessions[id] - if ok { + if _, ok := manager.sessions[id]; ok { manager.sessionsMu.Unlock() - return nil, fmt.Errorf("Session id already exists.") + return nil, "", fmt.Errorf("Session id already exists.") + } + + if _, ok := manager.tokens[token]; ok { + manager.sessionsMu.Unlock() + return nil, "", fmt.Errorf("Session token already exists.") } session := &SessionCtx{ id: id, + token: token, manager: manager, logger: manager.logger.With().Str("id", id).Logger(), profile: profile, } + manager.tokens[token] = id manager.sessions[id] = session manager.sessionsMu.Unlock() manager.emmiter.Emit("created", session) - return session, nil + return session, token, nil } func (manager *SessionManagerCtx) Update(id string, profile types.MemberProfile) error { @@ -87,6 +100,10 @@ func (manager *SessionManagerCtx) Delete(id string) error { return fmt.Errorf("Session id not found.") } + if _, ok := manager.tokens[session.token]; ok { + delete(manager.tokens, session.token) + } + delete(manager.sessions, id) manager.sessionsMu.Unlock() @@ -107,6 +124,18 @@ func (manager *SessionManagerCtx) Get(id string) (types.Session, bool) { return session, ok } +func (manager *SessionManagerCtx) GetByToken(token string) (types.Session, bool) { + manager.sessionsMu.Lock() + id, ok := manager.tokens[token] + manager.sessionsMu.Unlock() + + if !ok { + return nil, false + } + + return manager.Get(id) +} + func (manager *SessionManagerCtx) List() []types.Session { manager.sessionsMu.Lock() defer manager.sessionsMu.Unlock() diff --git a/internal/session/session.go b/internal/session/session.go index c58dfdbf..701b9d45 100644 --- a/internal/session/session.go +++ b/internal/session/session.go @@ -10,6 +10,7 @@ import ( type SessionCtx struct { id string + token string logger zerolog.Logger manager *SessionManagerCtx profile types.MemberProfile diff --git a/internal/types/session.go b/internal/types/session.go index bea5acef..443ed042 100644 --- a/internal/types/session.go +++ b/internal/types/session.go @@ -59,10 +59,11 @@ type Session interface { } type SessionManager interface { - Create(profile MemberProfile) (Session, error) + Create(profile MemberProfile) (Session, string, error) Update(id string, profile MemberProfile) error - Get(id string) (Session, bool) Delete(id string) error + Get(id string) (Session, bool) + GetByToken(token string) (Session, bool) List() []Session SetHost(host Session)