diff options
-rw-r--r-- | errors/errors.go | 7 | ||||
-rw-r--r-- | main.go | 2 | ||||
-rw-r--r-- | user/user.go | 10 | ||||
-rw-r--r-- | user/validators.go | 83 |
4 files changed, 88 insertions, 14 deletions
diff --git a/errors/errors.go b/errors/errors.go index c16bd52..0d88490 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -1,5 +1,5 @@ /* openbills - Server for web based Libre Billing Software - * Copyright (C) 2023 Vidhu Kant Sharma <vidhukant@vidhukant.com> + * Copyright (C) 2023-2024 Vidhu Kant Sharma <vidhukant@vidhukant.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,6 +31,9 @@ var ( ErrEmptyContactName = errors.New("Contact Name Cannot Be Empty") ErrInvalidGSTIN = errors.New("Invalid GSTIN") ErrInvalidEmail = errors.New("Invalid E-Mail Address") + ErrEmptyEmail = errors.New("E-Mail Address Cannot Be Empty") + ErrInvalidUsername = errors.New("Invalid Username") + ErrEmptyUsername = errors.New("Username Cannot Be Empty") ErrInvalidPhone = errors.New("Invalid Phone Number") ErrInvalidWebsite = errors.New("Invalid Website URL") ErrEmptyBrandName = errors.New("Brand Name Cannot Be Empty") @@ -38,6 +41,8 @@ var ( ErrInvalidGSTPercentage = errors.New("Invalid GST Percentage") ErrPasswordTooShort = errors.New("Password Is Too Short") ErrPasswordTooLong = errors.New("Password Is Too Long") + ErrUsernameTooShort = errors.New("Username Is Too Short") + ErrUsernameTooLong = errors.New("Username Is Too Long") ErrInvalidLoginMethod = errors.New("Login Method Can Only Be 'email' Or 'username'") // 401 @@ -38,7 +38,7 @@ import ( "log" ) -const OPENBILLS_VERSION = "v0.4.0" +const OPENBILLS_VERSION = "v0.5.0" func init() { if !viper.GetBool("debug_mode") { diff --git a/user/user.go b/user/user.go index ee36e95..401ebe7 100644 --- a/user/user.go +++ b/user/user.go @@ -1,5 +1,5 @@ /* openbills - Server for web based Libre Billing Software - * Copyright (C) 2023 Vidhu Kant Sharma <vidhukant@vidhukant.com> + * Copyright (C) 2023-2024 Vidhu Kant Sharma <vidhukant@vidhukant.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ package user import ( d "vidhukant.com/openbills/db" e "vidhukant.com/openbills/errors" + u "vidhukant.com/openbills/util" "golang.org/x/crypto/bcrypt" "gorm.io/gorm" "github.com/spf13/viper" @@ -38,8 +39,13 @@ func init() { type User struct { gorm.Model + u.Address + FullName string + Gstin string + Phone string + Email string + Website string Username string - Email string Password string IsVerified bool } diff --git a/user/validators.go b/user/validators.go index 647da06..b54457f 100644 --- a/user/validators.go +++ b/user/validators.go @@ -1,5 +1,5 @@ /* openbills - Server for web based Libre Billing Software - * Copyright (C) 2023 Vidhu Kant Sharma <vidhukant@vidhukant.com> + * Copyright (C) 2023-2024 Vidhu Kant Sharma <vidhukant@vidhukant.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,10 +19,10 @@ package user import ( "strings" - "net/mail" e "errors" "github.com/spf13/viper" "vidhukant.com/openbills/errors" + "vidhukant.com/openbills/util" ) func validatePassword(pass string) error { @@ -39,6 +39,26 @@ func validatePassword(pass string) error { return nil } +func validateUsername(username string) error { + // check if username is too short + if len(username) < viper.GetInt("username.min_username_length") { + return errors.ErrUsernameTooShort + } + + // check if username is too long + if len(username) > viper.GetInt("username.max_username_length") { + return errors.ErrUsernameTooLong + } + + for _, char := range username { + if !strings.Contains(username, string(char)) { + return errors.ErrInvalidUsername + } + } + + return nil +} + // NOTE: very inefficient and really really really dumb but it works // TODO: find a better (or even a remotely good) way func validateUserField(field, value string) error { @@ -57,8 +77,14 @@ func validateUserField(field, value string) error { switch(field) { case "username": return errors.ErrNonUniqueUsername + case "phone": + return errors.ErrNonUniquePhone case "email": return errors.ErrNonUniqueEmail + case "website": + return errors.ErrNonUniqueWebsite + case "gstin": + return errors.ErrNonUniqueGSTIN default: return e.New(field + " is not unique") } @@ -71,20 +97,57 @@ func validateUserField(field, value string) error { func (u *User) validate() error { u.Username = strings.TrimSpace(u.Username) u.Email = strings.TrimSpace(u.Email) + u.Phone = strings.TrimSpace(u.Phone) + u.Website = strings.TrimSpace(u.Website) + u.Gstin = strings.TrimSpace(u.Gstin) u.IsVerified = false // TODO: validate username length and stuff + + // don't validate if GSTIN is empty + if u.Gstin != "" && !util.ValidateGstin(u.Gstin) { + return errors.ErrInvalidGSTIN + } - var err error + // don't validate if phone is empty + if u.Phone != "" && !util.ValidatePhone(u.Phone) { + return errors.ErrInvalidPhone + } - // validate email - _, err = mail.ParseAddress(u.Email) - if err != nil { - return errors.ErrInvalidEmail - } + // don't validate if website is empty + if u.Website != "" && !util.ValidateWebsite(u.Website) { + return errors.ErrInvalidWebsite + } + + // don't accept empty email + if u.Email == "" { + return errors.ErrEmptyEmail + } else { + // validate email + if !util.ValidateEmail(u.Email) { + return errors.ErrInvalidEmail + } + } + + // don't accept empty username + if u.Username == "" { + return errors.ErrEmptyUsername + } else { + // validate username + err := validateUsername(u.Username) + if err != nil { + return err + } + } + + // validate password + err := validatePassword(u.Password) + if err != nil { + return err + } - for _, i := range [][]string{{"username", u.Username}, {"email", u.Email}} { - err = validateUserField(i[0], i[1]) + for _, i := range [][]string{{"username", u.Username}, {"email", u.Email}, {"website", u.Website}, {"gstin", u.Gstin}, {"phone", u.Phone}} { + err := validateUserField(i[0], i[1]) if err != nil { return err } |