mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-04 18:31:41 +00:00
feature/1109 grpc session model (#1141)
- **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**
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user