mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-02-12 16:12:44 +00:00
174 lines
4.5 KiB
Go
174 lines
4.5 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/go-errors/errors"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const (
|
|
// All constant here are used for frontend responses
|
|
NotFound = "Not found"
|
|
InvalidData = "Missing or invalid data"
|
|
Unauthorized = "Authorization failed"
|
|
Forbidden = "Access denied"
|
|
ServerError = "Internal server error"
|
|
InvalidCompanyID = "Invalid company ID"
|
|
InvalidDomainID = "Invalid domain ID"
|
|
InvalidMessageID = "Invalid message ID"
|
|
InvalidPageID = "Invalid page ID"
|
|
InvalidPageTypeID = "Invalid page type ID"
|
|
InvalidRecipientID = "Invalid recipient ID"
|
|
InvalidRecipientGroupID = "Invalid recipient group ID"
|
|
InvalidSMTPConfigurationID = "Invalid SMTP configuration ID"
|
|
CompanyNotFound = "Company not found"
|
|
)
|
|
|
|
// JSONResponse is the response structure for the API
|
|
type JSONResponse struct {
|
|
Success bool `json:"success"`
|
|
Data any `json:"data"`
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
// JSONResponseHandler is a interface for API responses
|
|
type JSONResponseHandler interface {
|
|
OK(g *gin.Context, data any)
|
|
NotFound(g *gin.Context)
|
|
Unauthorized(g *gin.Context)
|
|
Forbidden(g *gin.Context)
|
|
BadRequest(g *gin.Context)
|
|
BadRequestMessage(g *gin.Context, message string)
|
|
ValidationFailed(g *gin.Context, field string, err error)
|
|
ServerError(g *gin.Context)
|
|
ServerErrorMessage(g *gin.Context, message string)
|
|
}
|
|
|
|
// jsonResponseHandler is a JSON API responder
|
|
type jsonResponseHandler struct{}
|
|
|
|
// NewJSONResponseHandler creates a new JSON responder
|
|
func NewJSONResponseHandler() JSONResponseHandler {
|
|
return &jsonResponseHandler{}
|
|
}
|
|
|
|
// newResponse creates a new JSON response
|
|
func (r *jsonResponseHandler) newResponse(
|
|
success bool,
|
|
data any,
|
|
errorMessage string,
|
|
) JSONResponse {
|
|
return JSONResponse{
|
|
Success: success,
|
|
Data: data,
|
|
Error: errorMessage,
|
|
}
|
|
}
|
|
|
|
// newOK creates a new OK response
|
|
func (r *jsonResponseHandler) newOK(data any) JSONResponse {
|
|
return r.newResponse(true, data, "")
|
|
}
|
|
|
|
// newError creates a new error response
|
|
func (r *jsonResponseHandler) newError(errorMessage string) JSONResponse {
|
|
return r.newResponse(false, nil, errorMessage)
|
|
}
|
|
|
|
// OK responds with 200 - OK
|
|
func (r *jsonResponseHandler) OK(g *gin.Context, data any) {
|
|
g.JSON(http.StatusOK, r.newOK(data))
|
|
}
|
|
|
|
// NotFound responds 404 - NOT FOUND
|
|
func (r *jsonResponseHandler) NotFound(g *gin.Context) {
|
|
g.JSON(
|
|
http.StatusNotFound,
|
|
r.newError(NotFound),
|
|
)
|
|
g.Abort()
|
|
}
|
|
|
|
// Unauthorized responds with 401 - UNAUTHORIZED
|
|
// generic error handler for authentication errors
|
|
func (r *jsonResponseHandler) Unauthorized(g *gin.Context) {
|
|
g.JSON(
|
|
http.StatusUnauthorized,
|
|
r.newError(Forbidden),
|
|
)
|
|
g.Abort()
|
|
}
|
|
|
|
// Forbidden responds with 403 - FORBIDDEN and a custom error message
|
|
// generic error handler for authorization errors
|
|
func (r *jsonResponseHandler) Forbidden(g *gin.Context) {
|
|
g.JSON(
|
|
http.StatusForbidden,
|
|
r.newError(Unauthorized),
|
|
)
|
|
g.Abort()
|
|
}
|
|
|
|
// BadRequest responds with 400 - BAD REQUEST
|
|
func (r *jsonResponseHandler) BadRequest(g *gin.Context) {
|
|
g.JSON(
|
|
http.StatusBadRequest,
|
|
r.newError(InvalidData),
|
|
)
|
|
g.Abort()
|
|
}
|
|
|
|
// BadRequestMessage responds with 400 - BAD REQUEST and a custom error message
|
|
func (r *jsonResponseHandler) BadRequestMessage(g *gin.Context, message string) {
|
|
g.JSON(
|
|
http.StatusBadRequest,
|
|
r.newError(message),
|
|
)
|
|
g.Abort()
|
|
}
|
|
|
|
func (r *jsonResponseHandler) unwrapErrorMessage(err error) string {
|
|
message := err.Error()
|
|
unwrapped := errors.Unwrap(err)
|
|
if unwrapped != nil {
|
|
message = r.unwrapErrorMessage(unwrapped)
|
|
}
|
|
return message
|
|
}
|
|
|
|
// ValidationFailed responds with 400 - BAD REQUEST and a validation error message
|
|
// that includes the field name and the validation error message
|
|
// if the err IS a ValidationError it will unwrap the validation error
|
|
// else it will use the error passed
|
|
func (r *jsonResponseHandler) ValidationFailed(g *gin.Context, field string, err error) {
|
|
message := r.unwrapErrorMessage(err)
|
|
g.JSON(
|
|
http.StatusBadRequest,
|
|
r.newError(
|
|
fmt.Sprintf("%s %s", field, message),
|
|
),
|
|
)
|
|
g.Abort()
|
|
}
|
|
|
|
// ServerError responds with 500 - INTERNAL SERVER ERROR
|
|
func (r *jsonResponseHandler) ServerError(g *gin.Context) {
|
|
g.JSON(
|
|
http.StatusInternalServerError,
|
|
r.newError(ServerError),
|
|
)
|
|
g.Abort()
|
|
}
|
|
|
|
// ServerError responds with 500 - INTERNAL SERVER ERROR and a custom error message
|
|
func (r *jsonResponseHandler) ServerErrorMessage(g *gin.Context, message string) {
|
|
g.JSON(
|
|
http.StatusInternalServerError,
|
|
r.newError(message),
|
|
)
|
|
g.Abort()
|
|
}
|