summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrailFinder <wohilas@gmail.com>2024-04-20 07:45:00 +0300
committerGrailFinder <wohilas@gmail.com>2024-04-20 07:45:00 +0300
commitb33be53ea9c0be523988a9412fd8e3f6a24782b3 (patch)
tree2f05cbfc78613f1771eb8143105859983cb91750
parentac70f43c3e52e35195353c73af5687b8286ff581 (diff)
Feat: add auth [wip]
-rw-r--r--components/error.html9
-rw-r--r--internal/handlers/auth.go81
-rw-r--r--internal/models/auth.go25
-rw-r--r--internal/server/router.go4
-rw-r--r--pkg/utils/main.go24
5 files changed, 142 insertions, 1 deletions
diff --git a/components/error.html b/components/error.html
new file mode 100644
index 0000000..51b6b05
--- /dev/null
+++ b/components/error.html
@@ -0,0 +1,9 @@
+{{define "error"}}
+<a href="/">
+ <div class="bg-orange-100 border-l-4 border-orange-500 text-orange-700 p-4" role="alert">
+ <p class="font-bold">An error from server</p>
+ <p>{{.}}</p>
+ <p>Click this banner to return to main page.</p>
+ </div>
+</a>
+{{end}}
diff --git a/internal/handlers/auth.go b/internal/handlers/auth.go
new file mode 100644
index 0000000..435f8ff
--- /dev/null
+++ b/internal/handlers/auth.go
@@ -0,0 +1,81 @@
+package handlers
+
+import (
+ "apjournal/internal/models"
+ "apjournal/pkg/utils"
+ "fmt"
+ "html/template"
+ "net/http"
+ "strings"
+ "time"
+)
+
+func abortWithError(w http.ResponseWriter, msg string) {
+ tmpl := template.Must(template.ParseGlob("components/*.html"))
+ tmpl.ExecuteTemplate(w, "error", msg)
+}
+
+func (h *Handlers) HandleLogin(w http.ResponseWriter, r *http.Request) {
+ r.ParseForm()
+ username := r.PostFormValue("username")
+ if username == "" {
+ msg := "username not provided"
+ h.log.Error(msg)
+ abortWithError(w, msg)
+ return
+ }
+ password := r.PostFormValue("password")
+ if password == "" {
+ msg := "password not provided"
+ h.log.Error(msg)
+ abortWithError(w, msg)
+ return
+ }
+ cleanName := utils.RemoveSpacesFromStr(username)
+ // allNames := h.s.CacheGetAllNames()
+ allNames := []string{}
+ if utils.StrInSlice(cleanName, allNames) {
+ err := fmt.Errorf("name: %s already taken", cleanName)
+ h.log.Error("already taken", "error", err)
+ abortWithError(w, err.Error())
+ return
+ }
+ cookie, err := h.makeCookie(cleanName, r.RemoteAddr)
+ if err != nil {
+ h.log.Error("failed to login", "error", err)
+ abortWithError(w, err.Error())
+ }
+ http.SetCookie(w, cookie)
+ http.Redirect(w, r, "/", 302)
+}
+
+func (h *Handlers) makeCookie(username string, remote string) (*http.Cookie, error) {
+ // Create a new random session token
+ // sessionToken := xid.New().String()
+ sessionToken := "token"
+ expiresAt := time.Now().Add(time.Duration(h.cfg.SessionLifetime) * time.Second)
+ // Set the token in the session map, along with the session information
+ session := &models.Session{
+ Username: username,
+ Expiry: expiresAt,
+ }
+ // TODO: write session to db
+ cookie := &http.Cookie{
+ Name: "session_token",
+ Value: sessionToken,
+ Secure: true,
+ HttpOnly: true,
+ SameSite: http.SameSiteNoneMode,
+ Domain: h.cfg.ServerConfig.Host,
+ }
+ h.log.Info("check remote addr for cookie set",
+ "remote", remote, "session", session)
+ if strings.Contains(remote, "192.168.0") {
+ // no idea what is going on
+ // domainName = "192.168.0.101"
+ cookie.Domain = "192.168.0.101"
+ }
+ // set ctx?
+ // c.Set("username", username)
+ return cookie, nil
+}
diff --git a/internal/models/auth.go b/internal/models/auth.go
new file mode 100644
index 0000000..5dadf8a
--- /dev/null
+++ b/internal/models/auth.go
@@ -0,0 +1,25 @@
+package models
+
+import (
+ "time"
+)
+
+// each session contains the username of the user and the time at which it expires
+type Session struct {
+ Username string
+ CurrentRoom string
+ Expiry time.Time
+}
+
+// we'll use this method later to determine if the session has expired
+func (s Session) IsExpired() bool {
+ return s.Expiry.Before(time.Now())
+}
+
+func ListUsernames(ss map[string]*Session) []string {
+ resp := make([]string, 0, len(ss))
+ for _, s := range ss {
+ resp = append(resp, s.Username)
+ }
+ return resp
+}
diff --git a/internal/server/router.go b/internal/server/router.go
index 75cf4f9..36c2083 100644
--- a/internal/server/router.go
+++ b/internal/server/router.go
@@ -10,7 +10,7 @@ func (srv *server) ListenToRequests() {
h := srv.actions
mux := http.NewServeMux()
server := &http.Server{
- Addr: "localhost:9000",
+ Addr: fmt.Sprintf("localhost:%d", srv.config.ServerConfig),
Handler: mux,
ReadTimeout: time.Second * 5,
WriteTimeout: time.Second * 5,
@@ -23,6 +23,8 @@ func (srv *server) ListenToRequests() {
mux.HandleFunc("GET /", h.MainPage)
mux.HandleFunc("POST /", h.HandleForm)
mux.HandleFunc("POST /done", h.HandleDoneAction)
+ mux.HandleFunc("POST /login", h.HandleLogin)
+ // mux.HandleFunc("POST /signup", h.HandleLogin)
// ====== elements ======
mux.HandleFunc("GET /showform", h.ServeShowForm)
diff --git a/pkg/utils/main.go b/pkg/utils/main.go
new file mode 100644
index 0000000..f49313e
--- /dev/null
+++ b/pkg/utils/main.go
@@ -0,0 +1,24 @@
+package utils
+
+import (
+ "strings"
+ "unicode"
+)
+
+func RemoveSpacesFromStr(origin string) string {
+ return strings.Map(func(r rune) rune {
+ if unicode.IsSpace(r) {
+ return -1
+ }
+ return r
+ }, origin)
+}
+
+func StrInSlice(key string, sl []string) bool {
+ for _, i := range sl {
+ if key == i {
+ return true
+ }
+ }
+ return false
+}