From a90bcaaa2d11a04e064effa886fdfc0047d95733 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Sat, 8 Jul 2023 14:28:15 +0200 Subject: [PATCH] login --- cmd/owl/create_author.go | 29 ++++++++++++++++++++++++++++ cmd/owl/main.go | 19 ++++++++++++++++-- cmd/owl/web.go | 21 ++++++++++++++++++++ go.mod | 3 +++ go.sum | 8 ++++++++ run_dev.sh | 6 ++++++ web/app.go | 2 +- web/editor_list_handler.go | 19 +----------------- web/login_handler.go | 35 +++++++++++++++++++++++++++++----- web/templates.go | 34 +++++++++++++++++++++++++++++++++ web/templates/views/login.tmpl | 16 ++++++++++++++++ 11 files changed, 166 insertions(+), 26 deletions(-) create mode 100644 cmd/owl/create_author.go create mode 100644 cmd/owl/web.go create mode 100755 run_dev.sh create mode 100644 web/templates.go create mode 100644 web/templates/views/login.tmpl diff --git a/cmd/owl/create_author.go b/cmd/owl/create_author.go new file mode 100644 index 0000000..d5f2a88 --- /dev/null +++ b/cmd/owl/create_author.go @@ -0,0 +1,29 @@ +package main + +import ( + "owl-blogs/infra" + + "github.com/spf13/cobra" +) + +var user string +var password string + +func init() { + rootCmd.AddCommand(newAuthorCmd) + + newAuthorCmd.Flags().StringVarP(&user, "user", "u", "", "The user name") + newAuthorCmd.MarkFlagRequired("user") + newAuthorCmd.Flags().StringVarP(&password, "password", "p", "", "The password") + newAuthorCmd.MarkFlagRequired("password") +} + +var newAuthorCmd = &cobra.Command{ + Use: "new-author", + Short: "Creates a new author", + Long: `Creates a new author`, + Run: func(cmd *cobra.Command, args []string) { + db := infra.NewSqliteDB(DbPath) + App(db).AuthorService.Create(user, password) + }, +} diff --git a/cmd/owl/main.go b/cmd/owl/main.go index 6a557c1..a51435d 100644 --- a/cmd/owl/main.go +++ b/cmd/owl/main.go @@ -1,15 +1,31 @@ package main import ( + "fmt" + "os" "owl-blogs/app" "owl-blogs/config" "owl-blogs/domain/model" "owl-blogs/infra" "owl-blogs/web" + + "github.com/spf13/cobra" ) const DbPath = "owlblogs.db" +var rootCmd = &cobra.Command{ + Use: "owl", + Short: "Owl Blogs is a not so static blog generator", +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + func App(db infra.Database) *web.WebApp { config := config.NewConfig() @@ -29,6 +45,5 @@ func App(db infra.Database) *web.WebApp { } func main() { - db := infra.NewSqliteDB(DbPath) - App(db).Run() + Execute() } diff --git a/cmd/owl/web.go b/cmd/owl/web.go new file mode 100644 index 0000000..1eac414 --- /dev/null +++ b/cmd/owl/web.go @@ -0,0 +1,21 @@ +package main + +import ( + "owl-blogs/infra" + + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(webCmd) +} + +var webCmd = &cobra.Command{ + Use: "web", + Short: "Start the web server", + Long: `Start the web server`, + Run: func(cmd *cobra.Command, args []string) { + db := infra.NewSqliteDB(DbPath) + App(db).Run() + }, +} diff --git a/go.mod b/go.mod index 1ccf3ca..35d83e3 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/gofiber/fiber/v2 v2.47.0 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect github.com/klauspost/compress v1.16.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -18,6 +19,8 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect + github.com/spf13/cobra v1.7.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/testify v1.8.4 // indirect github.com/tinylib/msgp v1.1.8 // indirect diff --git a/go.sum b/go.sum index 6fc6625..d8332d0 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,6 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -8,6 +9,8 @@ github.com/gofiber/fiber/v2 v2.47.0 h1:EN5lHVCc+Pyqh5OEsk8fzRiifgwpbrP0rulQ4iNf3 github.com/gofiber/fiber/v2 v2.47.0/go.mod h1:mbFMVN1lQuzziTkkakgtKKdjfsXSw9BKR5lmcNksUoU= 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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= @@ -30,11 +33,16 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8= github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk= github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= diff --git a/run_dev.sh b/run_dev.sh new file mode 100755 index 0000000..a5521cb --- /dev/null +++ b/run_dev.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +set -e + +OWL_SECRET_KEY=test-secret-key \ +go run owl-blogs/cmd/owl web \ No newline at end of file diff --git a/web/app.go b/web/app.go index c08f763..b6d2fa9 100644 --- a/web/app.go +++ b/web/app.go @@ -28,7 +28,7 @@ func NewWebApp( entryHandler := NewEntryHandler(entryService, typeRegistry) mediaHandler := NewMediaHandler(entryService) rssHandler := NewRSSHandler(entryService) - loginHandler := NewLoginHandler(entryService) + loginHandler := NewLoginHandler(authorService) editorListHandler := NewEditorListHandler(typeRegistry) editorHandler := NewEditorHandler(entryService, typeRegistry, binService) diff --git a/web/editor_list_handler.go b/web/editor_list_handler.go index feafe33..ef7c52f 100644 --- a/web/editor_list_handler.go +++ b/web/editor_list_handler.go @@ -1,19 +1,13 @@ package web import ( - "embed" "owl-blogs/app" - "text/template" "github.com/gofiber/fiber/v2" ) -//go:embed templates -var templates embed.FS - type EditorListHandler struct { registry *app.EntryTypeRegistry - ts *template.Template } type EditorListContext struct { @@ -21,19 +15,8 @@ type EditorListContext struct { } func NewEditorListHandler(registry *app.EntryTypeRegistry) *EditorListHandler { - ts, err := template.ParseFS( - templates, - "templates/base.tmpl", - "templates/views/editor_list.tmpl", - ) - - if err != nil { - panic(err) - } - return &EditorListHandler{ registry: registry, - ts: ts, } } @@ -49,5 +32,5 @@ func (h *EditorListHandler) Handle(c *fiber.Ctx) error { typeNames = append(typeNames, name) } - return h.ts.ExecuteTemplate(c, "base", &EditorListContext{Types: typeNames}) + return RenderTemplate(c, "views/editor_list", &EditorListContext{Types: typeNames}) } diff --git a/web/login_handler.go b/web/login_handler.go index 0d6ff8e..99af413 100644 --- a/web/login_handler.go +++ b/web/login_handler.go @@ -2,22 +2,47 @@ package web import ( "owl-blogs/app" + "time" "github.com/gofiber/fiber/v2" ) type LoginHandler struct { - entrySvc *app.EntryService + authorService *app.AuthorService } -func NewLoginHandler(entryService *app.EntryService) *LoginHandler { - return &LoginHandler{entrySvc: entryService} +func NewLoginHandler(authorService *app.AuthorService) *LoginHandler { + return &LoginHandler{authorService: authorService} } func (h *LoginHandler) HandleGet(c *fiber.Ctx) error { - return c.SendString("Hello, Login!") + c.Set(fiber.HeaderContentType, fiber.MIMETextHTML) + return RenderTemplate(c, "views/login", nil) } func (h *LoginHandler) HandlePost(c *fiber.Ctx) error { - return c.SendString("Hello, Login!") + c.Set(fiber.HeaderContentType, fiber.MIMETextHTML) + name := c.FormValue("name") + password := c.FormValue("password") + + valid := h.authorService.Authenticate(name, password) + if !valid { + return c.Redirect("/auth/login") + } + + token, err := h.authorService.CreateToken(name) + if err != nil { + return err + } + + cookie := fiber.Cookie{ + Name: "token", + Value: token, + Expires: time.Now().Add(30 * 24 * time.Hour), + HTTPOnly: true, + } + c.Cookie(&cookie) + + return c.Redirect("/editor/") + } diff --git a/web/templates.go b/web/templates.go new file mode 100644 index 0000000..7dee3a1 --- /dev/null +++ b/web/templates.go @@ -0,0 +1,34 @@ +package web + +import ( + "embed" + "io" + "text/template" +) + +//go:embed templates +var templates embed.FS + +func CreateTemplate(templateName string) (*template.Template, error) { + + return template.ParseFS( + templates, + "templates/base.tmpl", + "templates/"+templateName+".tmpl", + ) + +} + +func RenderTemplate(w io.Writer, templateName string, data interface{}) error { + + t, err := CreateTemplate(templateName) + + if err != nil { + return err + } + + err = t.ExecuteTemplate(w, "base", data) + + return err + +} diff --git a/web/templates/views/login.tmpl b/web/templates/views/login.tmpl new file mode 100644 index 0000000..b3bd630 --- /dev/null +++ b/web/templates/views/login.tmpl @@ -0,0 +1,16 @@ +{{define "title"}}Editor List{{end}} + +{{define "main"}} + +

Login

+ +
+ + + + + + + +
+{{end}} \ No newline at end of file