Last active
January 26, 2023 06:32
-
-
Save jonleopard/83cbddf300b55e2e0abb9346fb60fd3c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TRC runtime error: invalid memory address or nil pointer dereference | |
goroutine 5 [running]: | |
runtime/debug.Stack() | |
/usr/local/Cellar/go/1.19.5/libexec/src/runtime/debug/stack.go:24 +0x65 | |
main.(*application).serverError(0xc000280720, {0x1523030, 0xc0000b42a0}, {0x15203a0?, 0xc00040f3e0?}) | |
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/helpers.go:48 +0x66 | |
main.(*application).recoverPanic.func1.1() | |
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:51 +0x157 | |
panic({0x140b340, 0x178e830}) | |
/usr/local/Cellar/go/1.19.5/libexec/src/runtime/panic.go:884 +0x212 | |
github.com/jonleopard/mailmon/internal/database.(*Queries).GetUser(0x0, {0x1523570, 0xc000120000}, {0xc0000af380, 0xc}) | |
/Users/jon/projects/golang-learning/letsgo/mailmon/internal/database/query.sql.go:151 +0x95 | |
github.com/jonleopard/mailmon/internal/models.Authenticate({0xc0000af380?, 0xc0000aaa00?}, {0xc00041034e, 0x8}) | |
/Users/jon/projects/golang-learning/letsgo/mailmon/internal/models/users.go:34 +0x4e | |
main.(*application).handleUserLoginPost(0xc000280720, {0x1522d30, 0xc00009e0f0}, 0xc0000aaa00) | |
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/handlers.go:221 +0x31a | |
net/http.HandlerFunc.ServeHTTP(0xc000135540?, {0x1522d30?, 0xc00009e0f0?}, 0x0?) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f | |
github.com/alexedwards/scs/v2.(*SessionManager).LoadAndSave.func1({0x1523030, 0xc0000b42a0}, 0xc0000aa900) | |
/Users/jon/go/pkg/mod/github.com/alexedwards/scs/[email protected]/session.go:148 +0x216 | |
net/http.HandlerFunc.ServeHTTP(0xc0002808a0?, {0x1523030?, 0xc0000b42a0?}, 0xc0000c2170?) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f | |
github.com/go-chi/chi/v5.(*ChainHandler).ServeHTTP(0x1408a80?, {0x1523030?, 0xc0000b42a0?}, 0xc0004067c5?) | |
/Users/jon/go/pkg/mod/github.com/go-chi/chi/[email protected]/chain.go:31 +0x2c | |
github.com/go-chi/chi/v5.(*Mux).routeHTTP(0xc00007e4e0, {0x1523030, 0xc0000b42a0}, 0xc0000aa900) | |
/Users/jon/go/pkg/mod/github.com/go-chi/chi/[email protected]/mux.go:442 +0x216 | |
net/http.HandlerFunc.ServeHTTP(0xc000000140?, {0x1523030?, 0xc0000b42a0?}, 0xc0000aa900?) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f | |
github.com/go-chi/cors.(*Cors).Handler.func1({0x1523030, 0xc0000b42a0}, 0xc0000aa900) | |
/Users/jon/go/pkg/mod/github.com/go-chi/[email protected]/cors.go:228 +0x1bd | |
net/http.HandlerFunc.ServeHTTP(0x1523538?, {0x1523030?, 0xc0000b42a0?}, 0x178e5d0?) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f | |
github.com/go-chi/chi/v5.(*Mux).ServeHTTP(0xc00007e4e0, {0x1523030, 0xc0000b42a0}, 0xc0000aa800) | |
/Users/jon/go/pkg/mod/github.com/go-chi/chi/[email protected]/mux.go:88 +0x310 | |
main.secureHeaders.func1({0x1523030, 0xc0000b42a0}, 0x4?) | |
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:20 +0x3af | |
net/http.HandlerFunc.ServeHTTP(0xc00009c120?, {0x1523030?, 0xc0000b42a0?}, 0xc00014b9c8?) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f | |
main.(*application).logRequest.func1({0x1523030, 0xc0000b42a0}, 0xc0000aa800) | |
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:35 +0x19b | |
net/http.HandlerFunc.ServeHTTP(0x0?, {0x1523030?, 0xc0000b42a0?}, 0xffffffffffffffff?) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f | |
main.(*application).recoverPanic.func1({0x1523030?, 0xc0000b42a0?}, 0xc00014bae0?) | |
/Users/jon/projects/golang-learning/letsgo/mailmon/cmd/web/middleware.go:55 +0x93 | |
net/http.HandlerFunc.ServeHTTP(0x0?, {0x1523030?, 0xc0000b42a0?}, 0x12be934?) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2109 +0x2f | |
net/http.serverHandler.ServeHTTP({0x1522160?}, {0x1523030, 0xc0000b42a0}, 0xc0000aa800) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:2947 +0x30c | |
net/http.(*conn).serve(0xc000000a00, {0x15235e0, 0xc000280b10}) | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:1991 +0x607 | |
created by net/http.(*Server).Serve | |
/usr/local/Cellar/go/1.19.5/libexec/src/net/http/server.go:3102 +0x4db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func (app *application) handleUserSignupPost(w http.ResponseWriter, r *http.Request) { | |
// Declare an zero-valued instance of our userSignupForm struct. | |
var form models.UserSignupForm | |
// Parse the form data into the userSignupForm struct. | |
err := app.decodePostForm(r, &form) | |
if err != nil { | |
app.clientError(w, http.StatusBadRequest) | |
return | |
} | |
// Validate the form contents using our helper functions. | |
form.CheckField(validator.NotBlank(form.Name), "name", "This field cannot be blank") | |
form.CheckField(validator.NotBlank(form.Email), "email", "This field cannot be blank") | |
form.CheckField(validator.Matches(form.Email, validator.EmailRX), "email", "This field must be a valid email address") | |
form.CheckField(validator.NotBlank(form.Password), "password", "This field cannot be blank") | |
form.CheckField(validator.MinChars(form.Password, 8), "password", "This field must be at least 8 characters long") | |
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(form.Password), 12) | |
// If there are any errors, redisplay the signup form along with a 422 | |
// status code. | |
if !form.Valid() { | |
data := app.newTemplateData(r) | |
data.Form = form | |
app.render(w, http.StatusUnprocessableEntity, "signup.html", data) | |
return | |
} | |
// Try to create a new user record in the database. If the email already | |
// exists then add an error message to the form and re-display it. | |
// Do I need to return anything from the database? I am using _, err | |
err = app.repo.CreateUser(context.Background(), database.CreateUserParams{ | |
Name: form.Name, | |
Email: form.Email, | |
HashedPassword: string(hashedPassword), | |
}) | |
// TODO: Check if this is a sane way of checking for the 23505 error code. | |
if err != nil { | |
var pqErr *pq.Error | |
if errors.As(err, &pqErr) && pqErr.Code == "23505" { | |
form.AddFieldError("email", "Email address is already in use") | |
data := app.newTemplateData(r) | |
data.Form = form | |
app.render(w, http.StatusUnprocessableEntity, "signup.html", data) | |
} else { | |
app.serverError(w, err) | |
} | |
return | |
} | |
// Otherwise add a confirmation flash message to the session confirming that | |
// their signup worked. | |
app.sessionManager.Put(r.Context(), "flash", "Your signup was successful. Please log in.") | |
// And redirect the user to the login page. | |
http.Redirect(w, r, "/user/login", http.StatusSeeOther) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func (q *Queries) GetUser(ctx context.Context, email string) (*GetUserRow, error) { | |
row := q.db.QueryRowContext(ctx, getUser, email) | |
var i GetUserRow | |
err := row.Scan(&i.ID, &i.HashedPassword) | |
return &i, err | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func Authenticate(email, password string) (int, error) { | |
// Retrieve the id and hashed password associated with the given email. If | |
// no matching email exists we return the ErrInvalidCredentials error. | |
var id int | |
var hashedPassword []byte | |
repo := database.Repo{} | |
_, err := repo.GetUser(context.Background(), email) | |
if err != nil { | |
if errors.Is(err, sql.ErrNoRows) { | |
return 0, ErrInvalidCredentials | |
} else { | |
return 0, err | |
} | |
} | |
// Check whether the hashed password and plain-text password provided match. | |
// If they don't, we return the ErrInvalidCredentials error. | |
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(password)) | |
if err != nil { | |
if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) { | |
return 0, ErrInvalidCredentials | |
} else { | |
return 0, err | |
} | |
} | |
// Otherwise, the password is correct. Return the user ID. | |
return id, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment