feat: introduce AuthState enum for authentication state

This commit is contained in:
Prad Nukala 2024-10-11 19:03:14 -04:00
parent 9a3c8e000b
commit 58aa71997d
4 changed files with 28 additions and 47 deletions

View File

@ -45,6 +45,16 @@ func SessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
} }
} }
func defaultSession(id string, s *sessions.Session) *session {
return &session{
session: s,
id: id,
origin: "",
address: "",
chainID: "",
}
}
func getSessionID(ctx context.Context) (string, error) { func getSessionID(ctx context.Context) (string, error) {
sessionID, ok := ctx.Value(ctxKeySessionID{}).(string) sessionID, ok := ctx.Value(ctxKeySessionID{}).(string)
if !ok || sessionID == "" { if !ok || sessionID == "" {

View File

@ -2,38 +2,28 @@ package ctx
import "github.com/labstack/echo/v4" import "github.com/labstack/echo/v4"
type State string type AuthState string
const ( const (
StateAuthenticated State = "authenticated" Visitor AuthState = "visitor"
StateUnauthenticated State = "unauthenticated" Authenticated AuthState = "authenticated"
StatePendingCredentials State = "pending_credentials" Expired AuthState = "expired"
StatePendingAssertion State = "pending_assertion"
StateDisabled State = "disabled" PendingCredentials AuthState = "pending_credentials"
StateDisconnected State = "disconnected" PendingAssertion AuthState = "pending_assertion"
) )
func (s State) String() string { func (s AuthState) String() string {
return string(s) return string(s)
} }
func StateFromString(s string) State { func GetAuthState(c echo.Context) AuthState {
switch s { vals := c.Request().Header.Values("Authorization")
case StateAuthenticated.String(): if len(vals) == 0 {
return StateAuthenticated return Visitor
case StateUnauthenticated.String():
return StateUnauthenticated
case StatePendingCredentials.String():
return StatePendingCredentials
case StatePendingAssertion.String():
return StatePendingAssertion
case StateDisabled.String():
return StateDisabled
case StateDisconnected.String():
return StateDisconnected
default:
return State("")
} }
s := AuthState(c.Request().Header.Get("Authorization"))
return s
} }
func readSessionFromStore(c echo.Context, id string) (*session, error) { func readSessionFromStore(c echo.Context, id string) (*session, error) {

View File

@ -20,28 +20,15 @@ type Session interface {
GetChallenge(subject string) (WebBytes, error) GetChallenge(subject string) (WebBytes, error)
ValidateChallenge(challenge WebBytes, subject string) error ValidateChallenge(challenge WebBytes, subject string) error
IsState(State) bool
SaveHTTP(c echo.Context) error 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 { func NewSessionFromValues(vals map[interface{}]interface{}) *session {
s := &session{ s := &session{
id: vals["id"].(string), id: vals["id"].(string),
origin: vals["origin"].(string), origin: vals["origin"].(string),
address: vals["address"].(string), address: vals["address"].(string),
chainID: vals["chainID"].(string), chainID: vals["chainID"].(string),
state: StateFromString(vals["state"].(string)),
challenge: vals["challenge"].(WebBytes), challenge: vals["challenge"].(WebBytes),
subject: vals["subject"].(string), subject: vals["subject"].(string),
} }
@ -61,9 +48,6 @@ type session struct {
// Authentication // Authentication
challenge WebBytes // Webauthn mapping to Challenge; Per session based on origin challenge WebBytes // Webauthn mapping to Challenge; Per session based on origin
subject string // Webauthn mapping to User Displayable Name; Supplied by DWN frontend subject string // Webauthn mapping to User Displayable Name; Supplied by DWN frontend
// State
state State
} }
func (s *session) ID() string { func (s *session) ID() string {
@ -97,14 +81,9 @@ func (s *session) ValidateChallenge(challenge WebBytes, subject string) error {
return fmt.Errorf("invalid challenge") return fmt.Errorf("invalid challenge")
} }
s.subject = subject s.subject = subject
s.state = StateAuthenticated
return nil return nil
} }
func (s *session) IsState(state State) bool {
return s.state == state
}
func (s *session) SaveHTTP(c echo.Context) error { func (s *session) SaveHTTP(c echo.Context) error {
sess, err := store.Get(c.Request(), s.id) sess, err := store.Get(c.Request(), s.id)
if err != nil { if err != nil {
@ -123,7 +102,6 @@ func (s *session) Values() map[interface{}]interface{} {
vals["id"] = s.id vals["id"] = s.id
vals["address"] = s.address vals["address"] = s.address
vals["chainID"] = s.chainID vals["chainID"] = s.chainID
vals["state"] = s.state
vals["challenge"] = s.challenge vals["challenge"] = s.challenge
vals["subject"] = s.subject vals["subject"] = s.subject
return vals return vals

View File

@ -10,6 +10,9 @@ import (
func Route(c echo.Context) error { func Route(c echo.Context) error {
s := ctx.GetSession(c) s := ctx.GetSession(c)
log.Println(s.ID()) log.Printf("Session ID: %s", s.ID())
log.Printf("Session Origin: %s", s.Origin())
log.Printf("Session Address: %s", s.Address())
log.Printf("Session ChainID: %s", s.ChainID())
return ctx.RenderTempl(c, View()) return ctx.RenderTempl(c, View())
} }