Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>
read cookie and log user
auth/middleware.go | 44 ++++++++++++++++++++++++++++++++++++++++++-- cmd/server.go | 11 ++++++----- templates/index.html | 6 ++++++
diff --git a/auth/middleware.go b/auth/middleware.go index 2fc687ab90e439a3786394bd3f7f728967993bee..041352397cc30e77b7b87fe3d854ba1659bdb2c1 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -3,14 +3,17 @@ import ( "context" "fmt" + "errors" "net/http" "strings" "time" + "encoding/json" "golang.org/x/crypto/bcrypt" "git.eletrotupi.com/git/dinheiro/db" "git.eletrotupi.com/git/dinheiro/types" + "git.eletrotupi.com/git/dinheiro/keys" ) var authCtxKey = &contextKey{"auth"} @@ -28,7 +31,7 @@ UpdatedAt time.Time } type AuthCookie struct { - UserID int `json:"id"` + Email string `json:"email"` } func authError(writer http.ResponseWriter, reason string, statusCode int) { @@ -93,7 +96,14 @@ return } // TODO: Write the cookie part here - //authCookie = ... + authCookie := AuthCookie{Email: user.Email} + + cookieJson, err := json.Marshal(authCookie) + signedCookie := keys.Encrypt(cookieJson) + + expiration := time.Now().Add(365 * 24 * time.Hour) + cookie := http.Cookie{Name: "dinheiro.v1", Value: string(signedCookie), Expires: expiration} + http.SetCookie(w, &cookie) ctx := context.WithValue(r.Context(), authCtxKey, authCtx) r = r.WithContext(ctx) @@ -104,6 +114,27 @@ // This authenticate from an existing cookie sent by the browser // It'll decrypt the cookie, unmarshal into a AuthCookie struct // Then populate the AuthContext (our current user) func authFromCookie(cookie *http.Cookie, w http.ResponseWriter, r *http.Request, next http.Handler) { + payload := keys.DecryptWithoutExpiration([]byte(cookie.Value)) + if payload == nil { + authError(w, "Invalid cookie content", http.StatusForbidden) + } + + var authCookie AuthCookie + err := json.Unmarshal(payload, &authCookie) + if err != nil { + panic("aaaaa") + } + + authCtx, err := LookupUserAndGenerateCtx(r.Context(), authCookie.Email) + if err != nil { + authError(w, err.Error(), http.StatusForbidden) + + return + } + + ctx := context.WithValue(r.Context(), authCtxKey, authCtx) + r = r.WithContext(ctx) + next.ServeHTTP(w, r) } func Middleware() func(http.Handler) http.Handler { @@ -127,3 +158,12 @@ return }) } } + +func ForContext(ctx context.Context) (*AuthContext, error) { + raw, ok := ctx.Value(authCtxKey).(*AuthContext) + if !ok { + return nil, errors.New("No User") + } + + return raw, nil +} diff --git a/cmd/server.go b/cmd/server.go index 297e9b11235a804fdbd81cb5789eef7f05357750..598689ef49e1fa34d1aa62197802549571ae6214 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -7,6 +7,7 @@ "path/filepath" "strings" "net/http" "database/sql" + "html/template" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" @@ -54,14 +55,14 @@ func registerRoutes(router chi.Router) { registerStaticRoutes(router) router.Get("/", func(w http.ResponseWriter, r *http.Request) { - fileData, err := os.ReadFile("./templates/index.html") + authCtx, err := auth.ForContext(r.Context()) + parsedTemplate, _ := template.ParseFiles("templates/index.html") + err = parsedTemplate.Execute(w, authCtx) if err != nil { - log.Fatal("Couldn't open file") - os.Exit(1) + log.Println("Error executing template :", err) + return } - - w.Write(fileData) }) router.Post("/auth", func(w http.ResponseWriter, r *http.Request) { diff --git a/templates/index.html b/templates/index.html index 6fd2f07f1f1800ba6695b1eb1c5f6c56f3012d20..090a8a0ebb64633a9e4455c6c3651431905e4539 100644 --- a/templates/index.html +++ b/templates/index.html @@ -10,6 +10,12 @@ <body> <h1>Hello!</h1> + {{ if . }} + <p> Logged </p> + {{ else }} + <p> Not Logged </p> + {{ end }} + <div> <form method="POST" action="/auth"> <div>