mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
- **feat: remove Hway deployment** - **feat: introduce session middleware for requests** - **refactor: update path imports to use new pkg folder** - **feat: add gRPC client for interacting with services** - **feat: remove grpc client and use REST api** - **refactor: move from to** - **feat: add client views endpoint** - **feat: add webauthn support** - **closes: #1124** - **refactor: Improve PR labeler configuration** - **feat: add milestone discussion template** - **feat: remove OKR tracking issue template** - **feat: use gorilla sessions for session management** - **refactor: move pubkey related code to** - **<no value>** - **refactor: remove unused identifier type** - **feat: integrate Macaroon Keeper with Service Module** - **refactor: rename worker routes for clarity**
143 lines
3.1 KiB
Go
143 lines
3.1 KiB
Go
package ctx
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/go-webauthn/webauthn/protocol"
|
|
"github.com/gorilla/sessions"
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
type WebBytes = protocol.URLEncodedBase64
|
|
|
|
type Session interface {
|
|
ID() string
|
|
Origin() string
|
|
|
|
Address() string
|
|
ChainID() string
|
|
|
|
GetChallenge(subject string) (WebBytes, error)
|
|
ValidateChallenge(challenge WebBytes, subject string) error
|
|
|
|
IsState(State) bool
|
|
SaveHTTP(c echo.Context) error
|
|
}
|
|
|
|
func defaultSession(id string, s *sessions.Session) *session {
|
|
return &session{
|
|
session: s,
|
|
id: id,
|
|
origin: "",
|
|
address: "",
|
|
chainID: "",
|
|
state: StateUnauthenticated,
|
|
}
|
|
}
|
|
|
|
func NewSessionFromValues(vals map[interface{}]interface{}) *session {
|
|
s := &session{
|
|
id: vals["id"].(string),
|
|
origin: vals["origin"].(string),
|
|
address: vals["address"].(string),
|
|
chainID: vals["chainID"].(string),
|
|
state: StateFromString(vals["state"].(string)),
|
|
challenge: vals["challenge"].(WebBytes),
|
|
subject: vals["subject"].(string),
|
|
}
|
|
return s
|
|
}
|
|
|
|
type session struct {
|
|
// Defaults
|
|
session *sessions.Session
|
|
id string // Generated ksuid http cookie; Initialized on first request
|
|
origin string // Webauthn mapping to Relaying Party ID; Initialized on first request
|
|
|
|
// Initialization
|
|
address string // Webauthn mapping to User ID; Supplied by DWN frontend
|
|
chainID string // Macaroon mapping to location; Supplied by DWN frontend
|
|
|
|
// Authentication
|
|
challenge WebBytes // Webauthn mapping to Challenge; Per session based on origin
|
|
subject string // Webauthn mapping to User Displayable Name; Supplied by DWN frontend
|
|
|
|
// State
|
|
state State
|
|
}
|
|
|
|
func (s *session) ID() string {
|
|
return s.id
|
|
}
|
|
|
|
func (s *session) Origin() string {
|
|
return s.origin
|
|
}
|
|
|
|
func (s *session) Address() string {
|
|
return s.address
|
|
}
|
|
|
|
func (s *session) ChainID() string {
|
|
return s.chainID
|
|
}
|
|
|
|
func (s *session) GetChallenge(subject string) (WebBytes, error) {
|
|
if s.challenge == nil {
|
|
return nil, nil
|
|
}
|
|
return s.challenge, nil
|
|
}
|
|
|
|
func (s *session) ValidateChallenge(challenge WebBytes, subject string) error {
|
|
if s.challenge == nil {
|
|
return nil
|
|
}
|
|
if s.challenge.String() != challenge.String() {
|
|
return fmt.Errorf("invalid challenge")
|
|
}
|
|
s.subject = subject
|
|
s.state = StateAuthenticated
|
|
return nil
|
|
}
|
|
|
|
func (s *session) IsState(state State) bool {
|
|
return s.state == state
|
|
}
|
|
|
|
func (s *session) SaveHTTP(c echo.Context) error {
|
|
sess, err := store.Get(c.Request(), s.id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sess.Values = s.Values()
|
|
err = sess.Save(c.Request(), c.Response().Writer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *session) Values() map[interface{}]interface{} {
|
|
vals := make(map[interface{}]interface{})
|
|
vals["id"] = s.id
|
|
vals["address"] = s.address
|
|
vals["chainID"] = s.chainID
|
|
vals["state"] = s.state
|
|
vals["challenge"] = s.challenge
|
|
vals["subject"] = s.subject
|
|
return vals
|
|
}
|
|
|
|
func GetSession(c echo.Context) Session {
|
|
id, _ := getSessionID(c.Request().Context())
|
|
sess, _ := store.Get(c.Request(), id)
|
|
if sess.IsNew {
|
|
s := defaultSession(id, sess)
|
|
s.SaveHTTP(c)
|
|
return s
|
|
}
|
|
s, _ := readSessionFromStore(c, id)
|
|
return s
|
|
}
|