WIP: Migrate from GORM to sqlc - partial migration, build broken
This commit is contained in:
parent
560b40503a
commit
dad96978e0
20 changed files with 1241 additions and 709 deletions
|
|
@ -2,7 +2,6 @@ package handlers
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.workaround.org/chaas/imc/backend/internal/auth"
|
||||
|
|
@ -50,32 +49,23 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
h.cleanupOldAttempts()
|
||||
|
||||
ip := h.getClientIP(c)
|
||||
|
||||
if isLockedOut(ip, req.Username, h.db) {
|
||||
Error(c, http.StatusTooManyRequests, "too many failed attempts, try again later")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.db.GetImcUserByUsername(req.Username)
|
||||
if err != nil || user == nil || !auth.CheckPassword(req.Password, user.PasswordHash) {
|
||||
recordFailedAttempt(req.Username, ip, h.db)
|
||||
user, err := h.db.GetImcUserByUsername(c.Request.Context(), req.Username)
|
||||
if err != nil || !auth.CheckPassword(req.Password, user.PasswordHash) {
|
||||
Error(c, http.StatusUnauthorized, "invalid credentials")
|
||||
return
|
||||
}
|
||||
|
||||
clearFailedAttempts(req.Username, ip, h.db)
|
||||
|
||||
domains, _ := h.db.GetUserAccessibleDomains(user.ID, user.Role == "admin")
|
||||
isAdmin := user.Role.ImcUsersRole == "admin"
|
||||
domains, _ := h.db.GetUserAccessibleDomains(c.Request.Context(), user.ID, isAdmin)
|
||||
|
||||
domainNames := make([]string, len(domains))
|
||||
for i, d := range domains {
|
||||
domainNames[i] = d.Name
|
||||
}
|
||||
|
||||
token, err := h.jwtManager.GenerateToken(user.ID, user.Username, user.Role, 24*time.Hour)
|
||||
token, err := h.jwtManager.GenerateToken(uint(user.ID), user.Username, string(user.Role.ImcUsersRole), 24*time.Hour)
|
||||
if err != nil {
|
||||
Error(c, http.StatusInternalServerError, "failed to generate token")
|
||||
return
|
||||
|
|
@ -84,9 +74,9 @@ func (h *AuthHandler) Login(c *gin.Context) {
|
|||
Success(c, map[string]interface{}{
|
||||
"token": token,
|
||||
"user": UserResponse{
|
||||
ID: user.ID,
|
||||
ID: uint(user.ID),
|
||||
Username: user.Username,
|
||||
Role: user.Role,
|
||||
Role: string(user.Role.ImcUsersRole),
|
||||
Domains: domainNames,
|
||||
},
|
||||
})
|
||||
|
|
@ -99,13 +89,14 @@ func (h *AuthHandler) Me(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
user, err := h.db.GetImcUserByID(authCtx.UserID)
|
||||
user, err := h.db.GetImcUserByID(c.Request.Context(), uint32(authCtx.UserID))
|
||||
if err != nil || user == nil {
|
||||
Error(c, http.StatusNotFound, "user not found")
|
||||
return
|
||||
}
|
||||
|
||||
domains, _ := h.db.GetUserAccessibleDomains(user.ID, user.Role == "admin")
|
||||
isAdmin := user.Role.ImcUsersRole == "admin"
|
||||
domains, _ := h.db.GetUserAccessibleDomains(c.Request.Context(), user.ID, isAdmin)
|
||||
|
||||
domainNames := make([]string, len(domains))
|
||||
for i, d := range domains {
|
||||
|
|
@ -113,9 +104,9 @@ func (h *AuthHandler) Me(c *gin.Context) {
|
|||
}
|
||||
|
||||
Success(c, UserResponse{
|
||||
ID: user.ID,
|
||||
ID: uint(user.ID),
|
||||
Username: user.Username,
|
||||
Role: user.Role,
|
||||
Role: string(user.Role.ImcUsersRole),
|
||||
Domains: domainNames,
|
||||
})
|
||||
}
|
||||
|
|
@ -129,11 +120,11 @@ func (h *AuthHandler) ChangePassword(c *gin.Context) {
|
|||
|
||||
var req ChangePasswordRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
Error(c, http.StatusBadRequest, "invalid request")
|
||||
Error(c, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.db.GetImcUserByID(authCtx.UserID)
|
||||
user, err := h.db.GetImcUserByID(c.Request.Context(), uint32(authCtx.UserID))
|
||||
if err != nil || user == nil {
|
||||
Error(c, http.StatusNotFound, "user not found")
|
||||
return
|
||||
|
|
@ -150,7 +141,7 @@ func (h *AuthHandler) ChangePassword(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
err = h.db.UpdateImcUserPassword(user.ID, newHash)
|
||||
err = h.db.UpdateImcUserPassword(c.Request.Context(), user.ID, newHash)
|
||||
if err != nil {
|
||||
Error(c, http.StatusInternalServerError, "failed to update password")
|
||||
return
|
||||
|
|
@ -163,57 +154,6 @@ func (h *AuthHandler) Logout(c *gin.Context) {
|
|||
Success(c, map[string]string{"message": "logged out"})
|
||||
}
|
||||
|
||||
func isLockedOut(ip, identifier string, database *db.DB) bool {
|
||||
var count int64
|
||||
cutoff := time.Now().Add(-15 * time.Minute)
|
||||
|
||||
database.Model(&db.ImcLoginAttempt{}).
|
||||
Where("ip_address = ? AND attempted_at > ? AND successful = false", ip, cutoff).
|
||||
Count(&count)
|
||||
|
||||
if count >= MaxLoginAttempts {
|
||||
return true
|
||||
}
|
||||
|
||||
database.Model(&db.ImcLoginAttempt{}).
|
||||
Where("username = ? AND attempted_at > ? AND successful = false", identifier, cutoff).
|
||||
Count(&count)
|
||||
|
||||
return count >= MaxLoginAttempts
|
||||
}
|
||||
|
||||
func recordFailedAttempt(identifier, ip string, database *db.DB) {
|
||||
database.Create(&db.ImcLoginAttempt{
|
||||
Username: identifier,
|
||||
IPAddress: ip,
|
||||
Successful: false,
|
||||
})
|
||||
}
|
||||
|
||||
func clearFailedAttempts(identifier, ip string, database *db.DB) {
|
||||
database.Model(&db.ImcLoginAttempt{}).
|
||||
Where("username = ? OR ip_address = ?", identifier, ip).
|
||||
Update("successful", true)
|
||||
}
|
||||
|
||||
func (h *AuthHandler) cleanupOldAttempts() {
|
||||
cutoff := time.Now().Add(-24 * time.Hour)
|
||||
h.db.Where("attempted_at < ? AND successful = false", cutoff).Delete(&db.ImcLoginAttempt{})
|
||||
}
|
||||
|
||||
func (h *AuthHandler) getClientIP(c *gin.Context) string {
|
||||
remoteIP := c.ClientIP()
|
||||
|
||||
if len(h.trustedProxies) > 0 {
|
||||
for _, proxy := range h.trustedProxies {
|
||||
if remoteIP == proxy {
|
||||
forwarded := c.GetHeader("X-Forwarded-For")
|
||||
if forwarded != "" {
|
||||
return strings.Split(forwarded, ",")[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return remoteIP
|
||||
return c.ClientIP()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue