feat(mcp): session id store
This commit is contained in:
40
internal/mcp/session.go
Normal file
40
internal/mcp/session.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package mcp
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type SessionStore struct {
|
||||
mu sync.RWMutex
|
||||
m map[string]struct{}
|
||||
}
|
||||
|
||||
func NewSessionStore() *SessionStore {
|
||||
return &SessionStore{m: make(map[string]struct{})}
|
||||
}
|
||||
|
||||
func (s *SessionStore) Issue() string {
|
||||
b := make([]byte, 16)
|
||||
_, _ = rand.Read(b)
|
||||
id := hex.EncodeToString(b)
|
||||
|
||||
s.mu.Lock()
|
||||
s.m[id] = struct{}{}
|
||||
s.mu.Unlock()
|
||||
return id
|
||||
}
|
||||
|
||||
func (s *SessionStore) Valid(id string) bool {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
_, ok := s.m[id]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s *SessionStore) Drop(id string) {
|
||||
s.mu.Lock()
|
||||
delete(s.m, id)
|
||||
s.mu.Unlock()
|
||||
}
|
||||
22
internal/mcp/session_test.go
Normal file
22
internal/mcp/session_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package mcp_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.d-ma.be/mathias/gitea-mcp/internal/mcp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSessionStoreIssueAndCheck(t *testing.T) {
|
||||
s := mcp.NewSessionStore()
|
||||
|
||||
id := s.Issue()
|
||||
assert.NotEmpty(t, id)
|
||||
assert.Len(t, id, 32)
|
||||
|
||||
assert.True(t, s.Valid(id))
|
||||
assert.False(t, s.Valid("bogus"))
|
||||
|
||||
s.Drop(id)
|
||||
assert.False(t, s.Valid(id))
|
||||
}
|
||||
Reference in New Issue
Block a user