From 04ebbfda87375eab7dab8d67b2f372f7d54c26be Mon Sep 17 00:00:00 2001 From: Florian Sylvain Date: Sun, 13 Aug 2023 00:24:50 +0200 Subject: [PATCH] feat: setup/register flow impl and login refactor --- .../gateways/web/templates/login.html | 5 +- .../gateways/web/templates/setup1.html | 102 ++++++++++++++++++ .../gateways/web/templates/setup2.html | 53 +++++++++ api/page.go | 34 +++++- api/{pageAuth.go => pageLogin.go} | 45 +++----- api/pageRegister.go | 76 +++++++++++++ api/pageRegisterConfirm.go | 10 ++ 7 files changed, 292 insertions(+), 33 deletions(-) create mode 100644 adapters/secondary/gateways/web/templates/setup1.html create mode 100644 adapters/secondary/gateways/web/templates/setup2.html rename api/{pageAuth.go => pageLogin.go} (58%) create mode 100644 api/pageRegister.go create mode 100644 api/pageRegisterConfirm.go diff --git a/adapters/secondary/gateways/web/templates/login.html b/adapters/secondary/gateways/web/templates/login.html index 0f1de38..30bf1cf 100644 --- a/adapters/secondary/gateways/web/templates/login.html +++ b/adapters/secondary/gateways/web/templates/login.html @@ -19,7 +19,10 @@
-

GohCMS

+
+

GohCMS

+

Connexion

+
diff --git a/adapters/secondary/gateways/web/templates/setup1.html b/adapters/secondary/gateways/web/templates/setup1.html new file mode 100644 index 0000000..6350b00 --- /dev/null +++ b/adapters/secondary/gateways/web/templates/setup1.html @@ -0,0 +1,102 @@ + + + + + + GohCMS | Installation + + + + + + + +
+
+
+

GohCMS

+

Création du compte administrateur

+
+ +
+
+ + +
+
+ + +
+
+ + +
{{.PageError.Message}}
+
+ +
+ +
+
+ + + + + diff --git a/adapters/secondary/gateways/web/templates/setup2.html b/adapters/secondary/gateways/web/templates/setup2.html new file mode 100644 index 0000000..6597d66 --- /dev/null +++ b/adapters/secondary/gateways/web/templates/setup2.html @@ -0,0 +1,53 @@ + + + + + + GohCMS | Installation + + + + + + + +
+
+
+

GohCMS

+

Installation terminée !

+
+

GohCMS est maintenant prêt à être utilisé.

+ +
+
+ + + + + diff --git a/api/page.go b/api/page.go index 16acc13..35cdfd6 100644 --- a/api/page.go +++ b/api/page.go @@ -6,6 +6,7 @@ import ( "io/fs" "net/http" "path/filepath" + "strings" ) //go:embed static @@ -26,6 +27,32 @@ type PageError struct { IsError bool `json:"isError"` } +func NewPageError(message string) *PageError { + return &PageError{ + Message: message, + IsError: strings.Compare(message, "") != 0, + } +} + +func IsLoggedInMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !IsLoggedIn(r) { + http.Redirect(w, r, LoginRoute, http.StatusSeeOther) + return + } + next.ServeHTTP(w, r) + }) +} + +func GetLogin(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, LoginRoute, http.StatusPermanentRedirect) +} + +func GetLogout(w http.ResponseWriter, r *http.Request) { + RemoveJwtCookie(w) + http.Redirect(w, r, LoginRoute, http.StatusSeeOther) +} + func StaticFileServerWithContentType(fsys http.FileSystem) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { path := r.URL.Path @@ -52,12 +79,15 @@ func NewPageRouter() http.Handler { }) r.Get("/", GetLogin) - r.Get(LoginRoute, GetLoginPageHandler(NewLoginPage("", ""))) - r.Post(LoginRoute, GetLoginPageHandler(NewLoginPage("", ""))) + r.Get(LoginRoute, GetLoginPageHandler(EmptyLoginPage)) + r.Post(LoginRoute, GetLoginPageHandler(EmptyLoginPage)) + r.Get("/register", GetRegisterPageHandler(EmptyRegisterPage)) + r.Post("/register", GetRegisterPageHandler(EmptyRegisterPage)) r.Get("/logout", GetLogout) r.Group(func(r chi.Router) { r.Use(IsLoggedInMiddleware) + r.Get("/register-confirm", GetRegisterConfirmPage) r.Get("/home", GetHomePage) }) diff --git a/api/pageAuth.go b/api/pageLogin.go similarity index 58% rename from api/pageAuth.go rename to api/pageLogin.go index 2c7fc33..697c644 100644 --- a/api/pageAuth.go +++ b/api/pageLogin.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/http" "os" - "strings" ) const LoginRoute = "/login" @@ -15,14 +14,9 @@ type LoginPage struct { Username string `json:"username"` } -func NewLoginPage(error string, username string) *LoginPage { - return &LoginPage{ - PageError: &PageError{ - IsError: strings.Compare(error, "") != 0, - Message: error, - }, - Username: username, - } +var EmptyLoginPage = &LoginPage{ + PageError: NewPageError(""), + Username: "", } func GetLoginPageHandler(loginPage *LoginPage) http.HandlerFunc { @@ -35,6 +29,10 @@ func GetLoginPageHandler(loginPage *LoginPage) http.HandlerFunc { PostLoginPage(w, r) return } + if IsUserTableEmpty() { + http.Redirect(w, r, "/register", http.StatusSeeOther) + return + } bs, err := Container.GetPageUseCase.GetPage("login", &loginPage) if err != nil { _, _ = w.Write([]byte(err.Error())) @@ -52,7 +50,10 @@ func PostLoginPage(w http.ResponseWriter, r *http.Request) { }) if err != nil { r.Method = http.MethodGet - GetLoginPageHandler(NewLoginPage("Invalid username or password.", r.FormValue("username")))(w, r) + GetLoginPageHandler(&LoginPage{ + PageError: NewPageError("Invalid form data format."), + Username: r.FormValue("username"), + })(w, r) return } @@ -63,7 +64,10 @@ func PostLoginPage(w http.ResponseWriter, r *http.Request) { if err != nil || response.StatusCode != http.StatusOK { r.Method = http.MethodGet - GetLoginPageHandler(NewLoginPage("Invalid username or password.", r.FormValue("username")))(w, r) + GetLoginPageHandler(&LoginPage{ + PageError: NewPageError("Invalid username or password."), + Username: r.FormValue("username"), + })(w, r) return } @@ -71,22 +75,3 @@ func PostLoginPage(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/home", http.StatusSeeOther) } - -func GetLogin(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, LoginRoute, http.StatusPermanentRedirect) -} - -func GetLogout(w http.ResponseWriter, r *http.Request) { - RemoveJwtCookie(w) - http.Redirect(w, r, LoginRoute, http.StatusSeeOther) -} - -func IsLoggedInMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !IsLoggedIn(r) { - http.Redirect(w, r, LoginRoute, http.StatusSeeOther) - return - } - next.ServeHTTP(w, r) - }) -} diff --git a/api/pageRegister.go b/api/pageRegister.go new file mode 100644 index 0000000..1966dcf --- /dev/null +++ b/api/pageRegister.go @@ -0,0 +1,76 @@ +package api + +import ( + "bytes" + "encoding/json" + "net/http" + "os" +) + +type RegisterPage struct { + PageError *PageError `json:"error"` + Username string `json:"username"` + Email string `json:"email"` +} + +var EmptyRegisterPage = &RegisterPage{ + PageError: NewPageError(""), + Username: "", + Email: "", +} + +func GetRegisterPageHandler(registerPage *RegisterPage) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if IsLoggedIn(r) || !IsUserTableEmpty() { + http.Redirect(w, r, "/home", http.StatusSeeOther) + return + } + if r.Method == http.MethodPost { + PostRegisterPage(w, r) + return + } + bs, err := Container.GetPageUseCase.GetPage("setup1", ®isterPage) + if err != nil { + _, _ = w.Write([]byte(err.Error())) + } + _, _ = w.Write(bs) + } +} + +func PostRegisterPage(w http.ResponseWriter, r *http.Request) { + _ = r.ParseForm() + + credentials, err := json.Marshal(&UserRegister{ + Username: r.FormValue("username"), + Password: r.FormValue("password"), + Email: r.FormValue("email"), + }) + if err != nil { + r.Method = http.MethodGet + GetRegisterPageHandler(&RegisterPage{ + PageError: NewPageError("Invalid register form data format."), + Username: r.FormValue("username"), + Email: r.FormValue("email"), + })(w, r) + return + } + + response, err := http.Post( + "http://localhost:"+os.Getenv("PORT")+"/v1/auth/register", + "application/json", + bytes.NewBuffer(credentials)) + + if err != nil || response.StatusCode != http.StatusOK { + r.Method = http.MethodGet + GetRegisterPageHandler(&RegisterPage{ + PageError: NewPageError("Username should be between 3 and 20 characters long, password should be between 8 and 20 characters long, and email should be a valid email address."), + Username: r.FormValue("username"), + Email: r.FormValue("email"), + })(w, r) + return + } + + w.Header().Set("Set-Cookie", response.Header.Get("Set-Cookie")) + + http.Redirect(w, r, "/register-confirm", http.StatusSeeOther) +} diff --git a/api/pageRegisterConfirm.go b/api/pageRegisterConfirm.go new file mode 100644 index 0000000..7a6491d --- /dev/null +++ b/api/pageRegisterConfirm.go @@ -0,0 +1,10 @@ +package api + +import ( + "net/http" +) + +func GetRegisterConfirmPage(w http.ResponseWriter, _ *http.Request) { + registerConfirmTmpl, _ := Container.GetPageUseCase.GetPage("setup2", nil) + _, _ = w.Write(registerConfirmTmpl) +}