Login flow success

This commit is contained in:
Daniel Ponte 2022-10-26 18:27:24 -04:00
parent 963f4020b7
commit fb9ecb0509
5 changed files with 50 additions and 8 deletions

1
go.mod
View file

@ -12,6 +12,7 @@ require (
require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/copier v0.3.5 // indirect
github.com/labstack/gommon v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect

2
go.sum
View file

@ -11,6 +11,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/labstack/echo/v4 v4.6.1/go.mod h1:RnjgMWNDB9g/HucVWhQYNQP9PvbYf6adqftqryo7s9k=
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=

View file

@ -6,6 +6,7 @@ import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"dynatron.me/x/blasphem/pkg/frontend"
"dynatron.me/x/blasphem/pkg/storage"
@ -110,6 +111,7 @@ func (a *Authenticator) Check(f *Flow, rm map[string]interface{}) error {
success := p.ValidateCreds(rm)
if success {
log.Info().Str("user", rm["username"].(string)).Msg("Login success")
return nil
}
}

View file

@ -7,7 +7,10 @@ import (
"strings"
"time"
"github.com/jinzhu/copier"
"github.com/labstack/echo/v4"
"dynatron.me/x/blasphem/internal/common"
)
type FlowStore map[FlowID]*Flow
@ -27,7 +30,8 @@ type FlowSchemaItem struct {
type FlowType string
const (
TypeForm FlowType = "form"
TypeForm FlowType = "form"
TypeCreateEntry FlowType = "create_entry"
)
type FlowID string
@ -41,18 +45,18 @@ type Flow struct {
Type FlowType `json:"type"`
ID FlowID `json:"flow_id"`
Handler []*string `json:"handler"`
StepID Step `json:"step_id"`
StepID *Step `json:"step_id,omitempty"`
Schema []FlowSchemaItem `json:"data_schema"`
Errors interface{} `json:"errors"`
DescPlace *string `json:"description_placeholders"`
LastStep *string `json:"last_step"`
request *FlowRequest
age time.Time
ctime time.Time
}
func (f *Flow) touch() {
f.age = time.Now()
f.ctime = time.Now()
}
func genFlowID() FlowID {
@ -77,7 +81,7 @@ const cullAge = time.Minute * 30
func (fs FlowStore) cull() {
for k, v := range fs {
if time.Now().Sub(v.age) > cullAge {
if time.Now().Sub(v.ctime) > cullAge {
delete(fs, k)
}
}
@ -113,7 +117,7 @@ func (a *Authenticator) NewFlow(r *FlowRequest) *Flow {
flow := &Flow{
Type: TypeForm,
ID: genFlowID(),
StepID: StepInit,
StepID: stepPtr(StepInit),
Schema: sch,
Handler: r.Handler,
Errors: []string{},
@ -126,8 +130,19 @@ func (a *Authenticator) NewFlow(r *FlowRequest) *Flow {
return flow
}
func stepPtr(s Step) *Step { return &s }
func (f *Flow) redirect(c echo.Context) {
c.Request().Header.Set("Location", f.request.RedirectURI)
}
func (f *Flow) progress(a *Authenticator, c echo.Context) error {
switch f.StepID {
if f.StepID == nil {
c.Logger().Error("stepID is nil")
return c.String(http.StatusInternalServerError, "No Step ID")
}
switch *f.StepID {
case StepInit:
rm := make(map[string]interface{})
@ -146,9 +161,24 @@ func (f *Flow) progress(a *Authenticator, c echo.Context) error {
err = a.Check(f, rm)
switch err {
case nil:
var finishedFlow struct {
ID FlowID `json:"flow_id"`
Handler []*string `json:"handler"`
Result string `json:"result"`
Title string `json:"title"`
Type FlowType `json:"type"`
Version int `json:"version"`
}
// TODO: setup the session. delete the flow.
a.Flows.Remove(f)
return c.String(http.StatusOK, "login success!")
copier.Copy(&finishedFlow, f)
finishedFlow.Type = TypeCreateEntry
finishedFlow.Title = common.AppName
finishedFlow.Version = 1
f.redirect(c)
return c.JSON(http.StatusCreated, &finishedFlow)
case ErrInvalidHandler:
return c.String(http.StatusNotFound, err.Error())
case ErrInvalidAuth:
@ -211,6 +241,12 @@ func (a *Authenticator) LoginFlowHandler(c echo.Context) error {
return c.String(http.StatusNotFound, "no such flow")
}
if time.Now().Sub(flow.ctime) > cullAge {
a.Flows.Remove(flow)
return c.String(http.StatusGone, "flow timed out")
}
return flow.progress(a, c)
}

View file

@ -16,6 +16,7 @@ type User struct {
Password string `json:"password"`
Username string `json:"username"`
}
type HomeAssistantProvider struct {
AuthProviderBase `json:"-"`
Users []User `json:"users"`