mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-08-18 00:17:14 +02:00
Initial open source release
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
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()
|
||||
}
|
||||
Reference in New Issue
Block a user