diff --git a/go.mod b/go.mod index c24bb65..e34178c 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( require ( github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/google/uuid v1.3.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 diff --git a/go.sum b/go.sum index 529222c..f8709ab 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= diff --git a/pkg/auth/authenticator.go b/pkg/auth/authenticator.go index 004c3dd..62164f4 100644 --- a/pkg/auth/authenticator.go +++ b/pkg/auth/authenticator.go @@ -1,10 +1,12 @@ package auth import ( + "encoding/hex" "errors" "io" "net/http" + "github.com/google/uuid" "github.com/labstack/echo/v4" "github.com/rs/zerolog/log" @@ -19,9 +21,24 @@ var ( type Authenticator struct { Flows FlowStore + Sessions SessionStore Providers map[string]AuthProvider } +func (a *Authenticator) InstallRoutes(e *echo.Echo) { + authG := e.Group("/auth") + authG.GET("/authorize", a.AuthorizeHandler) + authG.GET("/providers", a.ProvidersHandler) + authG.POST("/token", a.TokenHandler) + + authG.POST("/login_flow", a.BeginLoginFlowHandler) + + loginFlow := authG.Group("/login_flow") // TODO: add IP address affinity middleware + loginFlow.POST("/:flow_id", a.LoginFlowHandler) + loginFlow.DELETE("/:flow_id", a.LoginFlowDeleteHandler) + +} + func (a *Authenticator) Provider(name string) AuthProvider { p, ok := a.Providers[name] if !ok { @@ -33,6 +50,7 @@ func (a *Authenticator) Provider(name string) AuthProvider { func (a *Authenticator) InitAuth(s storage.Store) error { a.Flows = make(FlowStore) + a.Sessions = make(SessionStore) hap, err := NewHAProvider(s) if err != nil { return err @@ -118,3 +136,10 @@ func (a *Authenticator) Check(f *Flow, rm map[string]interface{}) error { return ErrInvalidAuth } + +func genUUID() string { + // must be addressable + u := uuid.New() + + return hex.EncodeToString(u[:]) +} diff --git a/pkg/auth/flow.go b/pkg/auth/flow.go index 5da892a..27ff791 100644 --- a/pkg/auth/flow.go +++ b/pkg/auth/flow.go @@ -1,8 +1,6 @@ package auth import ( - "crypto/rand" - "encoding/hex" "net/http" "strings" "time" @@ -59,15 +57,6 @@ func (f *Flow) touch() { f.ctime = time.Now() } -func genFlowID() FlowID { - b := make([]byte, 16) - if _, err := rand.Read(b); err != nil { - panic(err) - } - - return FlowID(hex.EncodeToString(b)) -} - func (fs FlowStore) register(f *Flow) { fs.cull() fs[f.ID] = f @@ -116,7 +105,7 @@ func (a *Authenticator) NewFlow(r *FlowRequest) *Flow { flow := &Flow{ Type: TypeForm, - ID: genFlowID(), + ID: FlowID(genUUID()), StepID: stepPtr(StepInit), Schema: sch, Handler: r.Handler, @@ -164,7 +153,7 @@ func (f *Flow) progress(a *Authenticator, c echo.Context) error { var finishedFlow struct { ID FlowID `json:"flow_id"` Handler []*string `json:"handler"` - Result string `json:"result"` + Result TokenID `json:"result"` Title string `json:"title"` Type FlowType `json:"type"` Version int `json:"version"` @@ -175,6 +164,7 @@ func (f *Flow) progress(a *Authenticator, c echo.Context) error { finishedFlow.Type = TypeCreateEntry finishedFlow.Title = common.AppName finishedFlow.Version = 1 + finishedFlow.Result = a.NewToken(c.Request(), f) f.redirect(c) @@ -250,15 +240,6 @@ func (a *Authenticator) LoginFlowHandler(c echo.Context) error { return flow.progress(a, c) } -func (a *Authenticator) InstallRoutes(e *echo.Echo) { - authG := e.Group("/auth") - authG.GET("/authorize", a.AuthorizeHandler) - authG.GET("/providers", a.ProvidersHandler) - - authG.POST("/login_flow", a.BeginLoginFlowHandler) - - loginFlow := authG.Group("/login_flow") // TODO: add IP address affinity middleware - loginFlow.POST("/:flow_id", a.LoginFlowHandler) - loginFlow.DELETE("/:flow_id", a.LoginFlowDeleteHandler) - +func (a *Authenticator) TokenHandler(c echo.Context) error { + return c.String(http.StatusOK, "token good I guess") }