package api import ( "fmt" "net/http" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" "jp.wtf/go-fishing/internal/models" ) type CreateAnglerRequest struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } type Response struct { Data any `json:"$data,omitempty"` Meta *APIMetadata `json:"$meta,omitempty"` Error *APIError `json:"$error,omitempty"` } type APIMetadata struct { Version string `json:"version,omitempty"` } type APIErrorCode string const ( APIErrorCodeUnknown APIErrorCode = "API_ERR_UNKNOWN" APIErrorCodeUnauthorized APIErrorCode = "API_ERR_UNAUTHORIZED" APIErrorCodeNotFound APIErrorCode = "API_ERR_NOT_FOUND" APIErrorCodeInvalidBody APIErrorCode = "API_ERR_INVALID_BODY" APIErrorCodeInvalidRequest APIErrorCode = "API_ERR_INVALID_REQUEST" ) type APIError struct { Code APIErrorCode `json:"code"` Message string `json:"message"` } func SendJSONResponse(c *gin.Context, status int, response Response) { c.JSON(status, response) } func OK(c *gin.Context, data any) { SendJSONResponse(c, http.StatusOK, Response{ Data: data, Meta: &APIMetadata{ Version: c.GetString("APIVersion"), }, }) } func Fail(c *gin.Context, status int, code APIErrorCode, message string) { SendJSONResponse(c, status, Response{ Error: &APIError{ Code: code, Message: message, }, }) } func FailAndAbort(c *gin.Context, status int, code APIErrorCode, message string) { Fail(c, status, code, message) c.Abort() } func CheckIfLoggedIn(c *gin.Context) bool { s := sessions.Default(c) val := s.Get("angler_id") return val != nil && val != "" } func GetAnglerFromSession(c *gin.Context) (models.Angler, error) { val, exists := c.Get("angler") if !exists { return models.Angler{}, fmt.Errorf("No angler") } angler, ok := val.(models.Angler) if !ok { return models.Angler{}, fmt.Errorf("Malformed or invalid angler") } return angler, nil } func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) return string(bytes), err } func CheckPassword(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil }