Documentation
¶
Index ¶
- func CleanAll(input string) string
- func CleanInjection(input string) string
- func CleanPathTraversal(input string) string
- func CleanXSS(input string) string
- type FileUploadConfig
- type FileUploadResult
- type Helpers
- func (h *Helpers) CleanInjection(input string) string
- func (h *Helpers) CleanPathTraversal(input string) string
- func (h *Helpers) CleanXSS(input string) string
- func (h *Helpers) CreateDirIfNotExist(path string) error
- func (h *Helpers) CreateFileIfNotExist(path string) error
- func (h *Helpers) DownloadFile(w http.ResponseWriter, r *http.Request, pathToFile, fileName string) (string, error)
- func (h *Helpers) Error404(w http.ResponseWriter, r *http.Request)
- func (h *Helpers) Error500(w http.ResponseWriter, r *http.Request)
- func (h *Helpers) ErrorForbidden(w http.ResponseWriter, r *http.Request)
- func (h *Helpers) ErrorStatus(w http.ResponseWriter, status int)
- func (h *Helpers) ErrorUnauthorized(w http.ResponseWriter, r *http.Request)
- func (h *Helpers) Getenv(key string, defaultValue ...string) string
- func (h *Helpers) JsonError(w http.ResponseWriter, err interface{}, status int)
- func (h *Helpers) NewValidator(data url.Values) *Validation
- func (h *Helpers) RandomString(n int) string
- func (h *Helpers) ReadJSON(w http.ResponseWriter, r *http.Request, data interface{}, maxBytes ...int) error
- func (h *Helpers) Render(w http.ResponseWriter, r *http.Request, template string, ...) error
- func (h *Helpers) Sanitize(input string) string
- func (h *Helpers) UploadFile(r *http.Request, field string, config FileUploadConfig, fs filesystem.FS) (*FileUploadResult, error)
- func (h *Helpers) WriteJSON(w http.ResponseWriter, status int, data interface{}, headers ...http.Header) error
- func (h *Helpers) WriteXML(w http.ResponseWriter, status int, data interface{}, headers ...http.Header) error
- type Validation
- func (v *Validation) AddError(key, message string)
- func (v *Validation) Check(ok bool, key, message string)
- func (v *Validation) Has(field string, r *http.Request) bool
- func (v *Validation) HasJSON(json interface{}, fields ...string)
- func (v *Validation) IsDateISO(field, value string)
- func (v *Validation) IsEmail(field, value string)
- func (v *Validation) IsEmailInPublicDomain(field, value string)
- func (v *Validation) IsFloat(field, value string)
- func (v *Validation) IsInt(field, value string)
- func (v *Validation) NoSpaces(field, value string)
- func (v *Validation) NotEmpty(field, value string, message ...string)
- func (v *Validation) Password(field string, value string, length ...int)
- func (v *Validation) PasswordUncompromised(field string, value string, threshold ...int)
- func (v *Validation) Required(r *http.Request, fields ...string)
- func (v *Validation) RequiredJSON(json interface{}, fields ...string)
- func (v *Validation) StringLength(field, value string, minLength, maxLength int)
- func (v *Validation) ToString() string
- func (v *Validation) Valid() bool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CleanInjection ¶ added in v1.0.2
CleanInjection removes common injection attack vectors
func CleanPathTraversal ¶ added in v1.0.2
CleanPathTraversal removes directory traversal attempts
Types ¶
type FileUploadConfig ¶
type FileUploadConfig struct {
MaxSize int64
AllowedMimeTypes []string
TempDir string
Destination string
}
UploadConfig holds upload configuration
type FileUploadResult ¶
type FileUploadResult struct {
OriginalName string
SavedName string
MimeType string
Size int64
Path string
}
UploadResult contains information about uploaded file
type Helpers ¶
type Helpers struct {
FileUploadConfig FileUploadConfig
Redner *render.Render
}
func (*Helpers) CleanInjection ¶ added in v1.0.2
CleanInjection removes common injection attack vectors from user input. Protects against code injection, LDAP injection, and NoSQL injection by removing control characters and special LDAP characters.
Examples:
// Control character removal
input := "Hello\x00World\x08"
clean := h.CleanInjection(input)
// Result: "HelloWorld"
// LDAP injection protection
input := `admin)(uid=*`
clean := h.CleanInjection(input)
// Result: "adminuid=*"
// NoSQL injection protection
input := `{"$ne": null}`
clean := h.CleanInjection(input)
// Result: `{"$ne": null}` (parentheses removed if present)
func (*Helpers) CleanPathTraversal ¶ added in v1.0.2
CleanPathTraversal removes directory traversal attempts from user input. Protects against path traversal attacks by removing ../ and ..\ patterns.
Examples:
// Basic path traversal removal input := `../../../etc/passwd` clean := h.CleanPathTraversal(input) // Result: "etc/passwd" // Windows-style path traversal input := `..\..\..\windows\system32` clean := h.CleanPathTraversal(input) // Result: "windows\system32" // Mixed path separators input := `../documents/../../secret.txt` clean := h.CleanPathTraversal(input) // Result: "documents/secret.txt"
func (*Helpers) CleanXSS ¶ added in v1.0.2
CleanXSS removes XSS attack vectors from user input. Protects against Cross-Site Scripting by removing script tags, event handlers, and javascript: protocols, then escapes remaining HTML.
Examples:
// Script tag removal
input := `<script>alert('xss')</script>Hello`
clean := h.CleanXSS(input)
// Result: "Hello"
// Event handler removal
input := `<div onclick="malicious()">Content</div>`
clean := h.CleanXSS(input)
// Result: "<div>Content</div>"
// JavaScript protocol removal
input := `<a href="javascript:alert('xss')">Link</a>`
clean := h.CleanXSS(input)
// Result: "<a href="">Link</a>"
func (*Helpers) CreateDirIfNotExist ¶
Ensure that a specific directory exists at the given path. If the directory is absent, it proceeds to create it with predefined permissions. This function is useful in scenarios where you need to guarantee that a directory is present before performing operations that require its existence. A directory that is created will have octal value allows the owner to read, write, and execute files within the directory, while the group and others can only read and execute, not alter the content. Example:
Helpers.CreateDirIfNotExist(path)
func (*Helpers) CreateFileIfNotExist ¶
Ensure that a file at the given path exists. If it doesn't, it attempts to create the file. Example:
Helpers.CreateFileIfNotExist(path)
func (*Helpers) DownloadFile ¶ added in v1.0.4
func (h *Helpers) DownloadFile(w http.ResponseWriter, r *http.Request, pathToFile, fileName string) (string, error)
DownloadFile serves a file as a downloadable attachment to the client. It sets the Content-Disposition header to trigger a browser download dialog. The file path is sanitized using filepath.Clean to prevent directory traversal attacks. Returns the cleaned file path and any error that occurred.
Example:
func (a *App) DownloadReport(w http.ResponseWriter, r *http.Request) {
filePath, err := a.Helpers.DownloadFile(w, r, "/var/reports", "monthly-report.pdf")
if err != nil {
a.Helpers.Error500(w, r)
return
}
log.Printf("Served file: %s", filePath)
}
func (*Helpers) Error404 ¶ added in v1.0.4
func (h *Helpers) Error404(w http.ResponseWriter, r *http.Request)
Error404 sends a 404 Not Found response to the client.
Example:
func (a *App) GetUser(w http.ResponseWriter, r *http.Request) {
user, err := a.DB.FindUser(id)
if err != nil {
a.Helpers.Error404(w, r)
return
}
}
func (*Helpers) Error500 ¶ added in v1.0.4
func (h *Helpers) Error500(w http.ResponseWriter, r *http.Request)
Error500 sends a 500 Internal Server Error response to the client.
Example:
func (a *App) ProcessData(w http.ResponseWriter, r *http.Request) {
if err := a.Service.Process(); err != nil {
log.Printf("Processing failed: %v", err)
a.Helpers.Error500(w, r)
return
}
}
func (*Helpers) ErrorForbidden ¶ added in v1.0.4
func (h *Helpers) ErrorForbidden(w http.ResponseWriter, r *http.Request)
ErrorForbidden sends a 403 Forbidden response to the client. Use this when the user is authenticated but lacks permission for the requested resource.
Example:
func (a *App) AdminEndpoint(w http.ResponseWriter, r *http.Request) {
user := a.Auth.GetUser(r)
if !user.IsAdmin {
a.Helpers.ErrorForbidden(w, r)
return
}
}
func (*Helpers) ErrorStatus ¶ added in v1.0.4
func (h *Helpers) ErrorStatus(w http.ResponseWriter, status int)
ErrorStatus sends an error response with the specified HTTP status code. The response body contains the standard HTTP status text for the given code.
Example:
func (a *App) CustomError(w http.ResponseWriter, r *http.Request) {
// Send a 429 Too Many Requests
a.Helpers.ErrorStatus(w, http.StatusTooManyRequests)
// Send a 503 Service Unavailable
a.Helpers.ErrorStatus(w, http.StatusServiceUnavailable)
}
func (*Helpers) ErrorUnauthorized ¶ added in v1.0.4
func (h *Helpers) ErrorUnauthorized(w http.ResponseWriter, r *http.Request)
ErrorUnauthorized sends a 401 Unauthorized response to the client. Use this when authentication is required but not provided or invalid.
Example:
func (a *App) ProtectedEndpoint(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token == "" || !a.Auth.ValidateToken(token) {
a.Helpers.ErrorUnauthorized(w, r)
return
}
}
func (*Helpers) Getenv ¶
Get environment variable or return default if the value is an empty string. Example:
Helpers.Getenv("ADELE_API_ADDR", "localhost")
func (*Helpers) JsonError ¶ added in v1.0.4
func (h *Helpers) JsonError(w http.ResponseWriter, err interface{}, status int)
JsonError writes an error response in JSON format following RFC 7807 (Problem Details). Sets the Content-Type to "application/problem+json" and includes security headers.
Example:
func (a *App) CreateUser(w http.ResponseWriter, r *http.Request) {
// Validation error
a.Helpers.JsonError(w, map[string]string{
"error": "validation failed",
"field": "email",
}, http.StatusBadRequest)
// Or with a custom error struct
type APIError struct {
Code string `json:"code"`
Message string `json:"message"`
}
a.Helpers.JsonError(w, APIError{Code: "USER_EXISTS", Message: "User already exists"}, http.StatusConflict)
}
func (*Helpers) NewValidator ¶
func (h *Helpers) NewValidator(data url.Values) *Validation
Create new validator for use with a form.
Example: validator := helpers.NewValidator(r.Form)
func (*Helpers) RandomString ¶
RandomString generates a cryptographically secure random string of specified length using crypto/rand for entropy. The generated string contains alphanumeric characters (a-z, A-Z, 0-9) suitable for tokens, IDs, passwords, and other security-sensitive applications.
Example:
sessionID := helpers.RandomString(32) // Returns: "K7mX9pQr2NvB8zYtF3wL5cR1jP6sM4xH" apiKey := helpers.RandomString(16) // Returns: "aB9Xm2Qr7Kp3Nv8Z" tempPassword := helpers.RandomString(12) // Returns: "M9sK2pR7bN4X"
func (*Helpers) ReadJSON ¶ added in v1.0.4
func (h *Helpers) ReadJSON(w http.ResponseWriter, r *http.Request, data interface{}, maxBytes ...int) error
ReadJSON reads and decodes a JSON request body into the provided data structure. It limits the request body size to prevent memory exhaustion attacks. The maxBytes parameter is optional; if not provided, it defaults to 1048576 (1 MB). Returns an error if decoding fails or if the body contains more than one JSON value.
Example:
type CreateUserRequest struct {
Name string `json:"name"`
Email string `json:"email"`
}
func (a *App) CreateUser(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
// Use default 1MB limit
if err := a.Helpers.ReadJSON(w, r, &req); err != nil {
a.Helpers.JsonError(w, map[string]string{"error": err.Error()}, http.StatusBadRequest)
return
}
// Or specify custom limit (e.g., 512KB)
if err := a.Helpers.ReadJSON(w, r, &req, 524288); err != nil {
a.Helpers.JsonError(w, map[string]string{"error": err.Error()}, http.StatusBadRequest)
return
}
}
func (*Helpers) Sanitize ¶ added in v1.0.2
Sanitize removes common OWASP attack vectors from user input including XSS, injection attacks, and path traversal attempts. This method applies all sanitization functions and should be used on any untrusted user input.
Attack vectors protected against:
- Cross-Site Scripting (XSS): Removes <script> tags, event handlers, javascript: protocols
- Code Injection: Removes control characters and null bytes
- LDAP/NoSQL Injection: Removes special LDAP characters
- Path Traversal: Removes directory traversal patterns like ../
Examples:
// Basic XSS protection
input := `<script>alert('xss')</script>Hello`
clean := h.Sanitize(input)
// Result: "Hello"
// Event handler removal
input := `<div onclick="malicious()">Click me</div>`
clean := h.Sanitize(input)
// Result: "<div>Click me</div>"
// JavaScript protocol removal
input := `<a href="javascript:alert('xss')">Link</a>`
clean := h.Sanitize(input)
// Result: "<a href="">Link</a>"
// Path traversal protection
input := `../../../etc/passwd`
clean := h.Sanitize(input)
// Result: "etc/passwd"
// LDAP injection protection
input := `admin)(uid=*`
clean := h.Sanitize(input)
// Result: "adminuid=*"
// Control character removal
input := "Hello\x00World\x08"
clean := h.Sanitize(input)
// Result: "HelloWorld"
// Typical form input sanitization
username := h.Sanitize(r.Form.Get("username"))
comment := h.Sanitize(r.Form.Get("comment"))
filename := h.Sanitize(r.Form.Get("filename"))
Note: This function escapes HTML entities, so legitimate HTML will be converted to safe display text. For rich text that needs to preserve some HTML tags, consider using a more targeted approach or an HTML sanitization library.
func (*Helpers) UploadFile ¶
func (h *Helpers) UploadFile(r *http.Request, field string, config FileUploadConfig, fs filesystem.FS) (*FileUploadResult, error)
UploadFile safely handles multipart file uploads with validation, secure filename generation, and automatic cleanup. Validates MIME type and size, prevents path traversal attacks, and supports both local filesystem and custom storage backends. Example:
config := UploadConfig{
MaxSize: 10 << 20, // 10MB
AllowedMimeTypes: []string{"image/jpeg", "image/png"},
TempDir: "storage/tmp",
Destination: "storage/uploads",
}
result, err := app.UploadFile(r, "avatar", config, nil)
if err != nil {
return fmt.Errorf("upload failed: %w", err)
}
log.Printf("Uploaded %s as %s", result.OriginalName, result.SavedName)
func (*Helpers) WriteJSON ¶ added in v1.0.4
func (h *Helpers) WriteJSON(w http.ResponseWriter, status int, data interface{}, headers ...http.Header) error
WriteJSON encodes data as JSON and writes it to the response with the specified status code. The response is pretty-printed with indentation for readability. Optional headers can be provided to add custom HTTP headers to the response.
Example:
type UserResponse struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func (a *App) GetUser(w http.ResponseWriter, r *http.Request) {
user := UserResponse{ID: 1, Name: "John", Email: "[email protected]"}
// Basic usage
a.Helpers.WriteJSON(w, http.StatusOK, user)
// With custom headers
headers := http.Header{"X-Custom-Header": []string{"value"}}
a.Helpers.WriteJSON(w, http.StatusOK, user, headers)
}
func (*Helpers) WriteXML ¶ added in v1.0.4
func (h *Helpers) WriteXML(w http.ResponseWriter, status int, data interface{}, headers ...http.Header) error
WriteXML encodes data as XML and writes it to the response with the specified status code. The response is pretty-printed with indentation for readability. Optional headers can be provided to add custom HTTP headers to the response.
Example:
type ProductResponse struct {
XMLName xml.Name `xml:"product"`
ID int `xml:"id"`
Name string `xml:"name"`
Price float64 `xml:"price"`
}
func (a *App) GetProduct(w http.ResponseWriter, r *http.Request) {
product := ProductResponse{ID: 1, Name: "Widget", Price: 29.99}
a.Helpers.WriteXML(w, http.StatusOK, product)
}
type Validation ¶
func (*Validation) AddError ¶
func (v *Validation) AddError(key, message string)
AddError adds an error message to the validation errors map if the key doesn't already exist. The message supports :attribute placeholder which gets replaced with a formatted field name.
Example:
validator.AddError("email", "The :attribute field must be valid")
Results in: "The email field must be valid"
func (*Validation) Check ¶
func (v *Validation) Check(ok bool, key, message string)
Check adds an error message if the given condition is false. Useful for custom validation logic with conditional error reporting.
Example:
age, _ := strconv.Atoi(r.Form.Get("age"))
validator.Check(age >= 18, "age", "Must be 18 or older")
func (*Validation) Has ¶
func (v *Validation) Has(field string, r *http.Request) bool
Has checks if a field exists in the HTTP request form data and has a non-empty value. Returns true if the field exists and has content, false otherwise.
Example:
if validator.Has("username", r) {
Field exists and has a value
}
func (*Validation) HasJSON ¶
func (v *Validation) HasJSON(json interface{}, fields ...string)
HasJSON validates that specified fields exist in a JSON struct and contain non-empty values. Uses reflection to check both field existence and value content.
Example:
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
user := &User{Name: "John", Email: ""}
validator.HasJSON(user, "Name", "Email")
Name passes, Email fails validation
func (*Validation) IsDateISO ¶
func (v *Validation) IsDateISO(field, value string)
IsDateISO validates that a field contains a valid date in ISO format (YYYY-MM-DD). Uses Go's time.Parse with the standard date layout for validation.
Example:
birthDate := r.Form.Get("birth_date")
validator.IsDateISO("birth_date", birthDate)
Accepts "2023-12-25", "1990-01-01", but rejects "12/25/2023", "invalid"
func (*Validation) IsEmail ¶
func (v *Validation) IsEmail(field, value string)
IsEmail validates that a field contains a properly formatted email address. Uses the govalidator library for RFC-compliant email validation.
Example:
email := r.Form.Get("email")
validator.IsEmail("email", email)
Validates format like "[email protected]"
func (*Validation) IsEmailInPublicDomain ¶
func (v *Validation) IsEmailInPublicDomain(field, value string)
IsEmailInPublicDomain validates that an email address exists and is in a public domain. Uses govalidator's existence check which may perform DNS lookups.
Example:
email := r.Form.Get("email")
validator.IsEmailInPublicDomain("email", email)
Checks if email domain is reachable and public
func (*Validation) IsFloat ¶
func (v *Validation) IsFloat(field, value string)
IsFloat validates that a field contains a valid floating-point number. Uses strconv.ParseFloat with 64-bit precision for validation.
Example:
price := r.Form.Get("price")
validator.IsFloat("price", price)
Accepts "12.99", "0.5", "123", but rejects "abc", "12.34.56"
func (*Validation) IsInt ¶
func (v *Validation) IsInt(field, value string)
IsInt validates that a field contains a valid integer value. Uses strconv.Atoi for parsing validation.
Example:
quantity := r.Form.Get("quantity")
validator.IsInt("quantity", quantity)
Accepts "123", "-45", but rejects "12.5", "abc"
func (*Validation) NoSpaces ¶
func (v *Validation) NoSpaces(field, value string)
NoSpaces validates that a field contains no whitespace characters. Useful for usernames, slugs, or other fields that shouldn't contain spaces.
Example:
username := r.Form.Get("username")
validator.NoSpaces("username", username)
Accepts "john_doe", "user123", but rejects "john doe", "user name"
func (*Validation) NotEmpty ¶
func (v *Validation) NotEmpty(field, value string, message ...string)
NotEmpty validates that a field is not empty after trimming whitespace. Accepts optional custom error message, otherwise uses default message.
Example:
name := r.Form.Get("name")
validator.NotEmpty("name", name)
Or with custom message:
validator.NotEmpty("name", name, "Name cannot be blank")
func (*Validation) Password ¶
func (v *Validation) Password(field string, value string, length ...int)
Password validates that a password meets security requirements including minimum length, mixed case letters. Default minimum length is 12 characters.
Example:
password := r.Form.Get("password")
validator.Password("password", password) // Uses default 12 char minimum
validator.Password("password", password, 8) // Uses custom 8 char minimum
Requires uppercase, lowercase, and minimum length
func (*Validation) PasswordUncompromised ¶
func (v *Validation) PasswordUncompromised(field string, value string, threshold ...int)
PasswordUncompromised checks if a password appears in known data breaches using the HaveIBeenPwned API with k-anonymity (only sends first 5 chars of SHA1 hash). Optional threshold parameter sets minimum breach count to trigger error (default: 1).
Example:
password := r.Form.Get("password")
validator.PasswordUncompromised("password", password) // Any breach count fails
validator.PasswordUncompromised("password", password, 5) // Only fails if seen 5+ times
Checks against HaveIBeenPwned database securely
func (*Validation) Required ¶
func (v *Validation) Required(r *http.Request, fields ...string)
Required validates that specified fields exist and are not empty in the HTTP request form. Adds error messages for any missing or empty required fields.
Example:
validator.Required(r, "name", "email", "password") Checks that all three fields have values
func (*Validation) RequiredJSON ¶
func (v *Validation) RequiredJSON(json interface{}, fields ...string)
RequiredJSON validates that specified fields exist in a JSON struct using reflection. Checks if the provided interface contains the required fields as struct properties.
Example:
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
user := &User{}
validator.RequiredJSON(user, "Name", "Email")
func (*Validation) StringLength ¶ added in v1.0.2
func (v *Validation) StringLength(field, value string, minLength, maxLength int)
StringLength validates that a field's value is within the specified length range.
Example:
username := r.Form.Get("username")
validator.StringLength("username", username, 3, 50) // between 3-50 chars
validator.StringLength("username", username, 0, 50) // max 50 chars
func (*Validation) ToString ¶
func (v *Validation) ToString() string
ToString converts the Validation.Errors map to a human-readable string format. Useful for displaying all validation errors as a single message.
Example:
validator.Required(r, "name", "email")
if !validator.Valid() {
errorString := validator.ToString()
Returns: " Name is required Email is required"
}
func (*Validation) Valid ¶
func (v *Validation) Valid() bool
Test if any errors exist.
Example:
if !validator.Valid() {
... Handle validation fail
}