serve frontend from go

This commit is contained in:
u80864958
2025-05-05 10:00:50 +02:00
parent a06444c4df
commit 73a62b63ae
88 changed files with 76 additions and 36 deletions

View File

@ -0,0 +1,52 @@
package users
import (
"encoding/json"
"fmt"
"log"
"net/http"
"git.schreifuchs.ch/schreifuchs/ng-blog/internal/auth"
"git.schreifuchs.ch/schreifuchs/ng-blog/internal/model"
"golang.org/x/crypto/bcrypt"
)
// ChangePassword handles changing a user's password by decoding a request, validating input, hashing the password, and updating the database.
func (s Service) ChangePassword(w http.ResponseWriter, r *http.Request) {
var err error
var req Password
user := model.NewUser()
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
if claims, ok := auth.ExtractClaims(r.Context()); !ok {
log.Println("Error: was not able to extract Claims")
w.WriteHeader(http.StatusInternalServerError)
} else {
user.ID = claims.UserID
}
if len([]byte(req.Password)) > 72 {
fmt.Fprint(w, "Password to long, max 72 bytes")
w.WriteHeader(http.StatusBadRequest)
return
}
if user.Password, err = bcrypt.GenerateFromPassword([]byte(req.Password), 6); err != nil {
log.Println("Error: ", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
err = s.db.Model(&user).
Where("id = ?", user.ID).
Update("password", user.Password).
Error
if err != nil {
log.Printf("Error: %v", err)
w.WriteHeader(http.StatusInternalServerError)
}
w.WriteHeader(http.StatusOK)
}

View File

@ -0,0 +1,22 @@
package users
import (
"gorm.io/gorm"
)
// Service Represents a service with a database connection.
type Service struct {
db *gorm.DB
}
// Service - Creates a new Service instance, initializing it with a GORM database connection.
func New(db *gorm.DB) *Service {
return &Service{
db: db,
}
}
// Password struct represents a user's password with a JSON tag.
type Password struct {
Password string `json:"password"`
}

107
internal/users/roles.go Normal file
View File

@ -0,0 +1,107 @@
package users
import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"git.schreifuchs.ch/schreifuchs/ng-blog/internal/auth"
"git.schreifuchs.ch/schreifuchs/ng-blog/internal/model"
"github.com/google/uuid"
"github.com/gorilla/mux"
"gorm.io/gorm"
)
// GetUsers retrieves all users from the database and returns them as a JSON response.
func (s *Service) GetUsers(w http.ResponseWriter, r *http.Request) {
var users []model.User
err := s.db.Find(&users).Error
if err != nil {
log.Printf("Error while getting users: %v", err)
w.WriteHeader(http.StatusInternalServerError)
}
res, err := json.Marshal(&users)
if err != nil {
log.Printf("Error while marshaling users: %v", err)
w.WriteHeader(http.StatusInternalServerError)
}
w.Write(res)
}
// SetUserRole handles updating a user's role based on a UUID from the request.
func (s *Service) SetUserRole(w http.ResponseWriter, r *http.Request) {
var role model.Role
userUUIDstr, ok := mux.Vars(r)["userUUID"]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
userUUID, err := uuid.Parse(userUUIDstr)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
if err := json.NewDecoder(r.Body).Decode(&role); err != nil {
fmt.Fprint(w, err.Error())
w.WriteHeader(http.StatusBadRequest)
return
}
err = s.db.Model(&model.User{}).
Where("uuid = ?", userUUID).
Update("role", role).
Error
if err != nil {
log.Printf("Error while update user role: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
// DeleteUser handles the deletion of a user from the database, enforcing authorization checks.
func (s *Service) DeleteUser(w http.ResponseWriter, r *http.Request) {
claims, ok := auth.ExtractClaims(r.Context())
if !ok {
log.Println("Error while extracting claims")
w.WriteHeader(http.StatusInternalServerError)
return
}
userUUIDstr, ok := mux.Vars(r)["userUUID"]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
userUUID, err := uuid.Parse(userUUIDstr)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
if claims.Role != model.RoleAdmin && userUUIDstr != claims.Subject {
w.WriteHeader(http.StatusForbidden)
return
}
if err = s.db.Where("uuid = ?", userUUID).Delete(&model.User{}).Error; err != nil {
if errors.Is(err, gorm.ErrCheckConstraintViolated) {
fmt.Fprint(w, "Username is already in use")
w.WriteHeader(http.StatusBadRequest)
return
}
log.Printf("Error: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}