Login flow success
This commit is contained in:
parent
963f4020b7
commit
fb9ecb0509
5 changed files with 50 additions and 8 deletions
1
go.mod
1
go.mod
|
@ -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
2
go.sum
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ type User struct {
|
|||
Password string `json:"password"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
type HomeAssistantProvider struct {
|
||||
AuthProviderBase `json:"-"`
|
||||
Users []User `json:"users"`
|
||||
|
|
Loading…
Reference in a new issue