add working signup + login

This commit is contained in:
sam 2023-09-04 03:33:13 +02:00
parent bc85b7c340
commit d8cb8c8fa8
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
27 changed files with 600 additions and 39 deletions

View file

@ -1,11 +1,92 @@
package auth
import (
"math"
"net/http"
"time"
"git.sleepycat.moe/sam/mercury/internal/database"
"github.com/flosch/pongo2/v6"
"github.com/rs/zerolog/log"
)
func (app *Auth) GetLogin(w http.ResponseWriter, r *http.Request) {
app.Template(w, r, "auth/login.tpl", pongo2.Context{})
app.Template(w, r, "auth/login.tpl", pongo2.Context{
"totp": false,
})
}
func (app *Auth) PostLogin(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
username := r.FormValue("username")
password := r.FormValue("password")
if username == "" {
app.Flash(w, "Username cannot be empty.")
app.Template(w, r, "auth/login.tpl", pongo2.Context{
"totp": false,
"flash_message": "Username cannot be empty.",
})
return
} else if password == "" {
app.Flash(w, "Password cannot be empty.")
app.Template(w, r, "auth/login.tpl", pongo2.Context{
"totp": false,
"flash_message": "Password cannot be empty.",
})
return
}
conn, err := app.Database.Acquire(ctx)
if err != nil {
log.Err(err).Msg("acquiring database connection")
return
}
defer conn.Release()
acct, err := app.Account(conn).ByUsername(ctx, username, "")
if err != nil {
log.Err(err).Msg("finding account")
app.Flash(w, "Username or password is invalid.")
app.Template(w, r, "auth/login.tpl", pongo2.Context{
"totp": false,
"flash_message": "Username or password is invalid.",
})
return
}
passwordValid, _ := acct.PasswordValid(password)
if !passwordValid {
app.Template(w, r, "auth/login.tpl", pongo2.Context{
"totp": false,
"flash_message": "Username or password is invalid.",
})
return
}
// TODO: totp
// create a new token
token, err := app.Token(conn).Create(
ctx, acct.ID, *app.DBConfig.Get().InternalApplication, []string{"all"}, time.Now().Add(math.MaxInt64))
if err != nil {
log.Err(err).Msg("creating token")
return
}
ts, err := app.TokenToJWT(token)
if err != nil {
log.Err(err).Msg("signing token string")
return
}
http.SetCookie(w, &http.Cookie{
Name: database.TokenCookieName,
Value: ts,
Path: "/",
Expires: token.Expires,
})
http.Redirect(w, r, "/web", http.StatusSeeOther)
}

67
web/auth/signup.go Normal file
View file

@ -0,0 +1,67 @@
package auth
import (
"net/http"
"git.sleepycat.moe/sam/mercury/internal/database/sql"
"github.com/flosch/pongo2/v6"
"github.com/rs/zerolog/log"
)
func (app *Auth) GetSignup(w http.ResponseWriter, r *http.Request) {
app.Template(w, r, "auth/signup.tpl", pongo2.Context{})
}
func (app *Auth) PostSignup(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
username := r.FormValue("username")
email := r.FormValue("email")
password := r.FormValue("password")
password2 := r.FormValue("repeat_password")
if username == "" {
app.Template(w, r, "auth/signup.tpl", pongo2.Context{"flash_message": "Username cannot be empty."})
return
} else if password == "" {
app.Template(w, r, "auth/signup.tpl", pongo2.Context{"flash_message": "Password cannot be empty."})
return
} else if password != password2 {
app.Template(w, r, "auth/signup.tpl", pongo2.Context{"flash_message": "Passwords don't match."})
return
} else if email == "" {
app.Template(w, r, "auth/signup.tpl", pongo2.Context{"flash_message": "Email address cannot be empty."})
return
}
tx, err := app.Database.BeginTx(ctx)
if err != nil {
log.Err(err).Msg("acquiring database connection")
return
}
defer tx.Rollback(ctx)
acct, err := app.Account(tx).CreateLocal(ctx, username, email, []byte(password))
if err != nil {
if err == sql.ErrUsernameTaken {
app.Template(w, r, "auth/signup.tpl", pongo2.Context{"flash_message": "Username is already taken."})
return
}
log.Err(err).Msg("creating account")
return
}
_, err = app.Blog(tx).Create(ctx, acct.ID, username)
if err != nil {
log.Err(err).Msg("creating blog")
return
}
err = tx.Commit(ctx)
if err != nil {
log.Err(err).Msg("committing transaction")
return
}
app.Flash(w, "Successfully created account!")
http.Redirect(w, r, "/auth/login", http.StatusSeeOther)
}