pye/auth/auth.go

79 lines
2.2 KiB
Go
Raw Normal View History

2024-10-12 21:45:00 +03:00
package auth
2024-10-11 11:38:08 +03:00
import (
2024-10-11 23:57:57 +03:00
"log/slog"
2024-10-11 11:38:08 +03:00
"net/http"
"net/mail"
"strings"
2024-10-12 21:45:00 +03:00
"git.a71.su/Andrew71/pye/storage"
2024-10-11 11:38:08 +03:00
)
2024-10-12 18:39:38 +03:00
func validEmail(email string) bool {
2024-10-11 11:38:08 +03:00
_, err := mail.ParseAddress(email)
return err == nil
}
2024-10-12 18:39:38 +03:00
func validPass(pass string) bool {
2024-10-12 09:55:58 +03:00
// TODO: Obviously, we *might* want something more sophisticated here
2024-10-12 16:59:47 +03:00
return len(pass) >= 8
2024-10-11 11:38:08 +03:00
}
2024-10-12 18:39:38 +03:00
2024-10-13 14:49:41 +03:00
// Register creates a new user with credentials provided through Basic Auth
2024-10-12 21:45:00 +03:00
func Register(w http.ResponseWriter, r *http.Request, data storage.Storage) {
2024-10-11 11:38:08 +03:00
email, password, ok := r.BasicAuth()
2024-10-12 09:55:58 +03:00
if ok {
2024-10-11 11:38:08 +03:00
email = strings.TrimSpace(email)
password = strings.TrimSpace(password)
2024-10-12 20:41:30 +03:00
if !(validEmail(email) && validPass(password) && !data.EmailExists(email)) {
2024-10-12 18:39:38 +03:00
slog.Debug("Outcome",
"email", validEmail(email),
"pass", validPass(password),
2024-10-12 20:41:30 +03:00
"taken", !data.EmailExists(email))
2024-10-12 16:59:47 +03:00
http.Error(w, "invalid auth credentials", http.StatusBadRequest)
2024-10-11 23:57:57 +03:00
return
2024-10-11 11:38:08 +03:00
}
2024-10-12 20:41:30 +03:00
err := data.AddUser(email, password)
2024-10-11 23:57:57 +03:00
if err != nil {
2024-10-12 20:41:30 +03:00
slog.Error("error adding a new user", "error", err)
http.Error(w, "error adding a new user", http.StatusInternalServerError)
2024-10-12 18:39:38 +03:00
return
2024-10-11 23:57:57 +03:00
}
2024-10-12 09:55:58 +03:00
w.WriteHeader(http.StatusCreated)
w.Write([]byte("User created"))
return
2024-10-11 11:38:08 +03:00
}
// No email and password was provided
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "This API requires authorization", http.StatusUnauthorized)
}
2024-10-11 23:57:57 +03:00
2024-10-13 14:49:41 +03:00
// Login returns JWT for a registered user through Basic Auth
2024-10-12 21:45:00 +03:00
func Login(w http.ResponseWriter, r *http.Request, data storage.Storage) {
2024-10-11 23:57:57 +03:00
email, password, ok := r.BasicAuth()
2024-10-12 09:55:58 +03:00
if ok {
2024-10-11 23:57:57 +03:00
email = strings.TrimSpace(email)
password = strings.TrimSpace(password)
2024-10-12 20:41:30 +03:00
user, ok := data.ByEmail(email)
2024-10-11 23:57:57 +03:00
if !ok || !user.PasswordFits(password) {
2024-10-12 20:41:30 +03:00
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
2024-10-12 16:59:47 +03:00
http.Error(w, "you did something wrong", http.StatusUnauthorized)
2024-10-11 23:57:57 +03:00
return
}
2024-10-12 09:55:58 +03:00
s, err := CreateJWT(user)
if err != nil {
http.Error(w, "error creating jwt", http.StatusInternalServerError)
return
}
w.Write([]byte(s))
return
2024-10-11 23:57:57 +03:00
}
// No email and password was provided
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "This API requires authorization", http.StatusUnauthorized)
2024-10-12 09:55:58 +03:00
}