mirror of
https://git.freecumextremist.com/grumbulon/pomme.git
synced 2024-11-22 11:23:46 +00:00
move files around, make sure cookies work, and add logout
This commit is contained in:
parent
c7893eb38e
commit
f469d20e06
4 changed files with 140 additions and 90 deletions
|
@ -2,10 +2,8 @@ package api
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -14,8 +12,6 @@ import (
|
|||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/jwtauth/v5"
|
||||
"github.com/go-chi/render"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func SetDBMiddleware(next http.Handler) http.Handler {
|
||||
|
@ -47,10 +43,12 @@ func Api() http.Handler {
|
|||
|
||||
})
|
||||
|
||||
// Open routes
|
||||
api.Group(func(api chi.Router) {
|
||||
api.Use(SetDBMiddleware)
|
||||
api.With(SetDBMiddleware).Post("/create", NewUser)
|
||||
api.With(SetDBMiddleware).Post("/login", Login)
|
||||
api.Post("/logout", Logout)
|
||||
})
|
||||
|
||||
return api
|
||||
|
@ -72,92 +70,6 @@ func Ingest(w http.ResponseWriter, r *http.Request) {
|
|||
// todo -- add functions to apply to master zonefile if above check is OK
|
||||
}
|
||||
|
||||
func NewUser(w http.ResponseWriter, r *http.Request) {
|
||||
db, ok := r.Context().Value("DB").(*gorm.DB)
|
||||
if !ok {
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var result internal.User
|
||||
|
||||
r.ParseForm()
|
||||
username := r.Form.Get("username")
|
||||
if username == "" {
|
||||
username = autoUname()
|
||||
}
|
||||
password := r.Form.Get("password")
|
||||
if password == "" {
|
||||
http.Error(w, "No password entered", http.StatusInternalServerError)
|
||||
}
|
||||
db.Where("username = ?", username).First(&result)
|
||||
|
||||
if result.Username != "" {
|
||||
http.Error(w, "User already exists", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
db.Create(&internal.User{Username: username, HashedPassword: string(hashedPassword)})
|
||||
data := internal.Response{
|
||||
Username: username,
|
||||
HTTPResponse: http.StatusCreated,
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(data)
|
||||
}
|
||||
|
||||
func Login(w http.ResponseWriter, r *http.Request) {
|
||||
var result internal.User
|
||||
r.ParseForm()
|
||||
username := r.Form.Get("username")
|
||||
if username == "" {
|
||||
username = autoUname()
|
||||
}
|
||||
password := r.Form.Get("password")
|
||||
if password == "" {
|
||||
http.Error(w, "No password provided", http.StatusInternalServerError) // this should prob be handled by the frontend
|
||||
}
|
||||
|
||||
db, ok := r.Context().Value("DB").(*gorm.DB)
|
||||
if !ok {
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
db.Model(internal.User{Username: username}).First(&result)
|
||||
err := bcrypt.CompareHashAndPassword([]byte(result.HashedPassword), []byte(password))
|
||||
|
||||
if err != nil {
|
||||
basicAuthFailed(w, "user")
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
token := makeToken(username)
|
||||
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
HttpOnly: true,
|
||||
Expires: time.Now().Add(7 * 24 * time.Hour),
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
// Uncomment below for HTTPS:
|
||||
// Secure: true,
|
||||
Name: "jwt", // Must be named "jwt" or else the token cannot be searched for by jwtauth.Verifier.
|
||||
Value: token,
|
||||
})
|
||||
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
|
||||
}
|
||||
|
||||
func autoUname() string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
return fmt.Sprintf("user%d", rand.Intn(99999-00000))
|
||||
}
|
||||
|
||||
func AuthTest(w http.ResponseWriter, r *http.Request) {
|
||||
_, claims, _ := jwtauth.FromContext(r.Context())
|
||||
w.Write([]byte(fmt.Sprintf("protected area. hi %v", claims["user_id"])))
|
||||
|
|
78
internal/api/auth.go
Normal file
78
internal/api/auth.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.freecumextremist.com/grumbulon/pomme/internal"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Login(w http.ResponseWriter, r *http.Request) {
|
||||
var result internal.User
|
||||
r.ParseForm()
|
||||
username := r.Form.Get("username")
|
||||
if username == "" {
|
||||
username = autoUname()
|
||||
}
|
||||
password := r.Form.Get("password")
|
||||
if password == "" {
|
||||
http.Error(w, "No password provided", http.StatusInternalServerError) // this should prob be handled by the frontend
|
||||
}
|
||||
|
||||
db, ok := r.Context().Value("DB").(*gorm.DB)
|
||||
if !ok {
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
db.Model(internal.User{Username: username}).First(&result)
|
||||
err := bcrypt.CompareHashAndPassword([]byte(result.HashedPassword), []byte(password))
|
||||
|
||||
if err != nil {
|
||||
basicAuthFailed(w, "user")
|
||||
return
|
||||
}
|
||||
|
||||
token := makeToken(username)
|
||||
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
HttpOnly: true,
|
||||
Expires: time.Now().Add(7 * 24 * time.Hour),
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
// Uncomment below for HTTPS:
|
||||
// Secure: true,
|
||||
Name: "jwt", // Must be named "jwt" or else the token cannot be searched for by jwtauth.Verifier.
|
||||
Value: token,
|
||||
})
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(
|
||||
internal.Response{
|
||||
Message: "Successfully logged in",
|
||||
HTTPResponse: 200,
|
||||
Username: token,
|
||||
})
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
|
||||
}
|
||||
|
||||
func Logout(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
HttpOnly: true,
|
||||
MaxAge: -1, // Delete the cookie.
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
// Secure: true,
|
||||
Name: "jwt",
|
||||
Value: "",
|
||||
})
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(
|
||||
internal.Response{
|
||||
Message: "Successfully logged out",
|
||||
HTTPResponse: 200,
|
||||
})
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
}
|
59
internal/api/users.go
Normal file
59
internal/api/users.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.freecumextremist.com/grumbulon/pomme/internal"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewUser(w http.ResponseWriter, r *http.Request) {
|
||||
db, ok := r.Context().Value("DB").(*gorm.DB)
|
||||
if !ok {
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var result internal.User
|
||||
|
||||
r.ParseForm()
|
||||
username := r.Form.Get("username")
|
||||
if username == "" {
|
||||
username = autoUname()
|
||||
}
|
||||
password := r.Form.Get("password")
|
||||
if password == "" {
|
||||
http.Error(w, "No password entered", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
db.Where("username = ?", username).First(&result)
|
||||
|
||||
if result.Username != "" {
|
||||
http.Error(w, "User already exists", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
db.Create(&internal.User{Username: username, HashedPassword: string(hashedPassword)})
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(
|
||||
internal.Response{
|
||||
Username: username,
|
||||
HTTPResponse: http.StatusCreated,
|
||||
})
|
||||
}
|
||||
|
||||
func autoUname() string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
return fmt.Sprintf("user%d", rand.Intn(99999-00000))
|
||||
}
|
|
@ -39,6 +39,7 @@ type User struct {
|
|||
|
||||
type Response struct {
|
||||
Username string `json:"username"`
|
||||
Message string `json:"message"`
|
||||
HTTPResponse int `json:"status"`
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue