2023-07-24 15:17:15 +00:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
|
|
|
package form
|
|
|
|
|
|
|
|
import (
|
2023-08-15 20:35:21 +00:00
|
|
|
"context"
|
2023-07-24 15:17:15 +00:00
|
|
|
"errors"
|
|
|
|
"net/mail"
|
2023-08-15 20:35:21 +00:00
|
|
|
"net/url"
|
|
|
|
"regexp"
|
|
|
|
|
|
|
|
"dev.tandem.ws/tandem/camper/pkg/database"
|
|
|
|
"dev.tandem.ws/tandem/camper/pkg/locale"
|
2023-07-24 15:17:15 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Validator struct {
|
|
|
|
l *locale.Locale
|
|
|
|
AllOK bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewValidator(l *locale.Locale) *Validator {
|
|
|
|
return &Validator{
|
|
|
|
l: l,
|
|
|
|
AllOK: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Validator) CheckRequired(input *Input, message string) bool {
|
|
|
|
return v.check(input, input.Val != "", message)
|
|
|
|
}
|
|
|
|
|
2023-08-15 20:35:21 +00:00
|
|
|
func (v *Validator) CheckMinLength(input *Input, min int, message string) bool {
|
|
|
|
return v.check(input, len(input.Val) >= min, message)
|
|
|
|
}
|
|
|
|
|
2023-07-24 15:17:15 +00:00
|
|
|
func (v *Validator) CheckValidEmail(input *Input, message string) bool {
|
|
|
|
_, err := mail.ParseAddress(input.Val)
|
|
|
|
return v.check(input, err == nil, message)
|
|
|
|
}
|
|
|
|
|
2023-08-15 20:35:21 +00:00
|
|
|
func (v *Validator) CheckValidURL(input *Input, message string) bool {
|
|
|
|
_, err := url.Parse(input.Val)
|
|
|
|
return v.check(input, err == nil, message)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Validator) CheckValidVATIN(ctx context.Context, conn *database.Conn, input *Input, country string, message string) (bool, error) {
|
|
|
|
b, err := conn.GetBool(ctx, "select input_is_valid($1 || $2, 'vatin')", country, input.Val)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
return v.check(input, b, message), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Validator) CheckValidPhone(ctx context.Context, conn *database.Conn, input *Input, country string, message string) (bool, error) {
|
|
|
|
b, err := conn.GetBool(ctx, "select input_is_valid_phone($1, $2)", input.Val, country)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
return v.check(input, b, message), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Validator) CheckValidPostalCode(ctx context.Context, conn *database.Conn, input *Input, country string, message string) (bool, error) {
|
|
|
|
pattern, err := conn.GetText(ctx, "select '^' || postal_code_regex || '$' from country where country_code = $1", country)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
match, err := regexp.MatchString(pattern, input.Val)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
return v.check(input, match, message), nil
|
|
|
|
}
|
|
|
|
|
2023-07-26 18:46:09 +00:00
|
|
|
func (v *Validator) CheckPasswordConfirmation(password *Input, confirm *Input, message string) bool {
|
|
|
|
return v.check(confirm, password.Val == confirm.Val, message)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Validator) CheckSelectedOptions(field *Select, message string) bool {
|
|
|
|
return v.check(field, field.validOptionsSelected(), message)
|
|
|
|
}
|
|
|
|
|
Allow users to update their profile images
I do not see the profile image as an “integral part” of the user (i.e.,
no need for constraints), hence i do not want to store it in the
database, as would do for the identification image during check-in.
By default, i store the avatars in /var/lib/camper/avatars, but it is a
variable to allow packagers change this value using the linker.
This is also served as a test bed for uploading files to the server,
that now has a better interface and uses less resources that what i did
to Numerus.
Now the profile handler needs to keep a variable to know the path to the
avatars’ directory, thus i had to change it to a struct nested in app,
much like the fileHandler does. It still has to return the HandlerFunc,
however, as this function needs to close over the user and connection
variables.
Part of #7.
2023-07-28 18:15:09 +00:00
|
|
|
func (v *Validator) CheckImageFile(field *File, message string) bool {
|
|
|
|
return v.check(field, field.ContentType == "image/png" || field.ContentType == "image/jpeg", message)
|
|
|
|
}
|
|
|
|
|
2023-07-26 18:46:09 +00:00
|
|
|
type field interface {
|
|
|
|
setError(error)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Validator) check(field field, ok bool, message string) bool {
|
2023-07-24 15:17:15 +00:00
|
|
|
if !ok {
|
2023-07-26 18:46:09 +00:00
|
|
|
field.setError(errors.New(v.l.Get(message)))
|
2023-07-24 15:17:15 +00:00
|
|
|
v.AllOK = false
|
|
|
|
}
|
|
|
|
return ok
|
|
|
|
}
|