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 (
|
require (
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // 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/labstack/gommon v0.3.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // 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/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 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
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.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 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
|
||||||
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"dynatron.me/x/blasphem/pkg/frontend"
|
"dynatron.me/x/blasphem/pkg/frontend"
|
||||||
"dynatron.me/x/blasphem/pkg/storage"
|
"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)
|
success := p.ValidateCreds(rm)
|
||||||
|
|
||||||
if success {
|
if success {
|
||||||
|
log.Info().Str("user", rm["username"].(string)).Msg("Login success")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
|
"dynatron.me/x/blasphem/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FlowStore map[FlowID]*Flow
|
type FlowStore map[FlowID]*Flow
|
||||||
|
@ -28,6 +31,7 @@ type FlowType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TypeForm FlowType = "form"
|
TypeForm FlowType = "form"
|
||||||
|
TypeCreateEntry FlowType = "create_entry"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FlowID string
|
type FlowID string
|
||||||
|
@ -41,18 +45,18 @@ type Flow struct {
|
||||||
Type FlowType `json:"type"`
|
Type FlowType `json:"type"`
|
||||||
ID FlowID `json:"flow_id"`
|
ID FlowID `json:"flow_id"`
|
||||||
Handler []*string `json:"handler"`
|
Handler []*string `json:"handler"`
|
||||||
StepID Step `json:"step_id"`
|
StepID *Step `json:"step_id,omitempty"`
|
||||||
Schema []FlowSchemaItem `json:"data_schema"`
|
Schema []FlowSchemaItem `json:"data_schema"`
|
||||||
Errors interface{} `json:"errors"`
|
Errors interface{} `json:"errors"`
|
||||||
DescPlace *string `json:"description_placeholders"`
|
DescPlace *string `json:"description_placeholders"`
|
||||||
LastStep *string `json:"last_step"`
|
LastStep *string `json:"last_step"`
|
||||||
|
|
||||||
request *FlowRequest
|
request *FlowRequest
|
||||||
age time.Time
|
ctime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Flow) touch() {
|
func (f *Flow) touch() {
|
||||||
f.age = time.Now()
|
f.ctime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
func genFlowID() FlowID {
|
func genFlowID() FlowID {
|
||||||
|
@ -77,7 +81,7 @@ const cullAge = time.Minute * 30
|
||||||
|
|
||||||
func (fs FlowStore) cull() {
|
func (fs FlowStore) cull() {
|
||||||
for k, v := range fs {
|
for k, v := range fs {
|
||||||
if time.Now().Sub(v.age) > cullAge {
|
if time.Now().Sub(v.ctime) > cullAge {
|
||||||
delete(fs, k)
|
delete(fs, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +117,7 @@ func (a *Authenticator) NewFlow(r *FlowRequest) *Flow {
|
||||||
flow := &Flow{
|
flow := &Flow{
|
||||||
Type: TypeForm,
|
Type: TypeForm,
|
||||||
ID: genFlowID(),
|
ID: genFlowID(),
|
||||||
StepID: StepInit,
|
StepID: stepPtr(StepInit),
|
||||||
Schema: sch,
|
Schema: sch,
|
||||||
Handler: r.Handler,
|
Handler: r.Handler,
|
||||||
Errors: []string{},
|
Errors: []string{},
|
||||||
|
@ -126,8 +130,19 @@ func (a *Authenticator) NewFlow(r *FlowRequest) *Flow {
|
||||||
return 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 {
|
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:
|
case StepInit:
|
||||||
rm := make(map[string]interface{})
|
rm := make(map[string]interface{})
|
||||||
|
|
||||||
|
@ -146,9 +161,24 @@ func (f *Flow) progress(a *Authenticator, c echo.Context) error {
|
||||||
err = a.Check(f, rm)
|
err = a.Check(f, rm)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
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.
|
// TODO: setup the session. delete the flow.
|
||||||
a.Flows.Remove(f)
|
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:
|
case ErrInvalidHandler:
|
||||||
return c.String(http.StatusNotFound, err.Error())
|
return c.String(http.StatusNotFound, err.Error())
|
||||||
case ErrInvalidAuth:
|
case ErrInvalidAuth:
|
||||||
|
@ -211,6 +241,12 @@ func (a *Authenticator) LoginFlowHandler(c echo.Context) error {
|
||||||
return c.String(http.StatusNotFound, "no such flow")
|
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)
|
return flow.progress(a, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ type User struct {
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HomeAssistantProvider struct {
|
type HomeAssistantProvider struct {
|
||||||
AuthProviderBase `json:"-"`
|
AuthProviderBase `json:"-"`
|
||||||
Users []User `json:"users"`
|
Users []User `json:"users"`
|
||||||
|
|
Loading…
Reference in a new issue