Compare commits
5 Commits
0aa332c26b
...
82413499f5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82413499f5 | ||
|
|
df82782ba5 | ||
|
|
b42713b108 | ||
|
|
0d7c5674da | ||
|
|
46e09a1285 |
@@ -9,8 +9,7 @@
|
||||
"Host": "mail.server.com",
|
||||
"User": "username",
|
||||
"Password": "password",
|
||||
"Port": 465,
|
||||
"AdminEmail": "admin@server.com"
|
||||
"Port": 465
|
||||
},
|
||||
"templates": {
|
||||
"MailPath": "templates/email",
|
||||
@@ -23,7 +22,8 @@
|
||||
},
|
||||
"recipients": {
|
||||
"ContactForm": "contacts@server.com",
|
||||
"UserRegistration": "registration@server.com"
|
||||
"UserRegistration": "registration@server.com",
|
||||
"AdminEmail": "admin@server.com"
|
||||
},
|
||||
"security": {
|
||||
"RateLimits": {
|
||||
|
||||
@@ -30,11 +30,10 @@ type AuthenticationConfig struct {
|
||||
}
|
||||
|
||||
type SMTPConfig struct {
|
||||
Host string `json:"Host" envconfig:"SMTP_HOST"`
|
||||
User string `json:"User" envconfig:"SMTP_USER"`
|
||||
Password string `json:"Password" envconfig:"SMTP_PASS"`
|
||||
AdminEmail string `json:"AdminEmail" envconfig:"ADMIN_MAIL"`
|
||||
Port int `json:"Port" default:"465" envconfig:"SMTP_PORT"`
|
||||
Host string `json:"Host" envconfig:"SMTP_HOST"`
|
||||
User string `json:"User" envconfig:"SMTP_USER"`
|
||||
Password string `json:"Password" envconfig:"SMTP_PASS"`
|
||||
Port int `json:"Port" default:"465" envconfig:"SMTP_PORT"`
|
||||
}
|
||||
|
||||
type TemplateConfig struct {
|
||||
@@ -47,6 +46,7 @@ type TemplateConfig struct {
|
||||
type RecipientsConfig struct {
|
||||
ContactForm string `json:"ContactForm" envconfig:"RECIPIENT_CONTACT_FORM"`
|
||||
UserRegistration string `json:"UserRegistration" envconfig:"RECIPIENT_USER_REGISTRATION"`
|
||||
AdminEmail string `json:"AdminEmail" envconfig:"ADMIN_MAIL"`
|
||||
}
|
||||
|
||||
type SecurityConfig struct {
|
||||
|
||||
@@ -22,7 +22,7 @@ type RelayContactRequestTest struct {
|
||||
Assert bool
|
||||
}
|
||||
|
||||
func TestContactController(t *testing.T) {
|
||||
func testContactController(t *testing.T) {
|
||||
|
||||
tests := getContactData()
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -104,15 +104,15 @@ func TestSuite(t *testing.T) {
|
||||
// code := m.Run()
|
||||
|
||||
t.Run("userController", func(t *testing.T) {
|
||||
TestUserController(t)
|
||||
testUserController(t)
|
||||
})
|
||||
|
||||
t.Run("contactController", func(t *testing.T) {
|
||||
TestContactController(t)
|
||||
testContactController(t)
|
||||
})
|
||||
|
||||
t.Run("membershipController", func(t *testing.T) {
|
||||
TestMembershipController(t)
|
||||
testMembershipController(t)
|
||||
})
|
||||
|
||||
if err := utils.SMTPStop(); err != nil {
|
||||
|
||||
@@ -19,7 +19,7 @@ type RegisterSubscriptionTest struct {
|
||||
Assert bool
|
||||
}
|
||||
|
||||
func TestMembershipController(t *testing.T) {
|
||||
func testMembershipController(t *testing.T) {
|
||||
|
||||
tests := getSubscriptionData()
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -51,7 +51,7 @@ func (rt *RegisterUserTest) ValidateResult() error {
|
||||
return validateUser(rt.Assert, rt.WantDBData)
|
||||
}
|
||||
|
||||
func TestUserController(t *testing.T) {
|
||||
func testUserController(t *testing.T) {
|
||||
|
||||
tests := getTestUsers()
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"GoMembership/internal/constants"
|
||||
"GoMembership/internal/models"
|
||||
"GoMembership/pkg/logger"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"time"
|
||||
|
||||
"github.com/alexedwards/argon2id"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -29,6 +34,9 @@ func Open(dbPath string) error {
|
||||
DB = db
|
||||
|
||||
logger.Info.Print("Opened DB")
|
||||
if err := seedDatabase(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -40,3 +48,42 @@ func Close() error {
|
||||
}
|
||||
return db.Close()
|
||||
}
|
||||
|
||||
func seedDatabase() error {
|
||||
var count int64
|
||||
DB.Model(&models.User{}).Count(&count)
|
||||
if count == 0 {
|
||||
bytes := make([]byte, 12)
|
||||
_, err := rand.Read(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
password := hex.EncodeToString(bytes)
|
||||
hash, err := argon2id.CreateHash(password, argon2id.DefaultParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
admin := models.User{
|
||||
FirstName: "ad",
|
||||
LastName: "min",
|
||||
DateOfBirth: time.Now(),
|
||||
Password: hash,
|
||||
Address: "Downhill 4",
|
||||
ZipCode: "9999",
|
||||
City: "TechTown",
|
||||
Status: constants.ActiveStatus,
|
||||
RoleID: constants.Roles.Editor,
|
||||
}
|
||||
|
||||
result := DB.Create(&admin)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
logger.Error.Print("==============================================================")
|
||||
logger.Error.Printf("Admin Password: %v", password)
|
||||
logger.Error.Print("==============================================================")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
created_at DATETIME NOT NULL,
|
||||
updated_at DATETIME NOT NULL,
|
||||
first_name VARCHAR(50) NOT NULL,
|
||||
last_name VARCHAR(50) NOT NULL,
|
||||
phone VARCHAR(15),
|
||||
email VARCHAR(100) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
salt VARCHAR(255) NOT NULL,
|
||||
drivers_id_checked BOOLEAN,
|
||||
role_id INT,
|
||||
payment_status VARCHAR(50),
|
||||
date_of_birth DATE,
|
||||
address VARCHAR(255),
|
||||
profile_picture VARCHAR(255),
|
||||
notes TEXT,
|
||||
status VARCHAR(50),
|
||||
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE banking (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INT,
|
||||
iban VARCHAR(34) NOT NULL,
|
||||
bic VARCHAR(11) NOT NULL,
|
||||
mandate_reference VARCHAR(50),
|
||||
mandate_date_signed DATE,
|
||||
bank_name VARCHAR(100),
|
||||
account_holder_name VARCHAR(100),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE memberships (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
parent_id INT,
|
||||
model_id INT,
|
||||
start_date DATE,
|
||||
end_date DATE,
|
||||
status VARCHAR(50),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE membership_plans (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
monthly_fee DECIMAL(10, 2),
|
||||
hourly_rate DECIMAL(10, 2),
|
||||
included_hours_per_year INT,
|
||||
included_hours_per_month INT,
|
||||
conditions TEXT,
|
||||
details TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE rentals (
|
||||
id INTEGER PRIMARY KEY,
|
||||
car_id INT,
|
||||
user_id INT,
|
||||
start_datetime DATETIME NOT NULL,
|
||||
end_datetime DATETIME NOT NULL,
|
||||
booking_datetime DATETIME NOT NULL,
|
||||
total_cost DECIMAL(10, 2),
|
||||
payment_method VARCHAR(50),
|
||||
status VARCHAR(50),
|
||||
FOREIGN KEY (car_id) REFERENCES cars(id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE roles (
|
||||
id INTEGER PRIMARY KEY,
|
||||
role_name VARCHAR(50) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE consents (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INT,
|
||||
updated_at DATE,
|
||||
created_at DATE,
|
||||
first_name VARCHAR(255),
|
||||
last_name VARCHAR(255),
|
||||
email VARCHAR(255),
|
||||
consent_type VARCHAR(255),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE cars (
|
||||
id INTEGER PRIMARY KEY,
|
||||
licence_plate VARCHAR(15) NOT NULL UNIQUE,
|
||||
insurance VARCHAR(255) NOT NULL,
|
||||
acquired_date DATE NOT NULL,
|
||||
monthly_expenses DECIMAL(10, 2) NOT NULL,
|
||||
make VARCHAR(50),
|
||||
model VARCHAR(50),
|
||||
year INT,
|
||||
mileage INT,
|
||||
last_service_date DATE,
|
||||
status VARCHAR(50),
|
||||
vin VARCHAR(17) UNIQUE,
|
||||
fuel_type VARCHAR(20),
|
||||
gps BOOLEAN,
|
||||
current_location VARCHAR(255),
|
||||
service_history TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE email_verifications (
|
||||
id INTEGER PRIMARY KEY,
|
||||
user_id INT,
|
||||
verification_token VARCHAR(255) NOT NULL,
|
||||
created_at DATETIME NOT NULL,
|
||||
verified_at DATETIME DEFAULT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
@@ -1,9 +1,14 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"GoMembership/internal/config"
|
||||
"GoMembership/pkg/logger"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -15,6 +20,26 @@ import (
|
||||
func TestAuthMiddleware(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to get current working directory: %v", err)
|
||||
}
|
||||
configFilePath := filepath.Join(cwd, "..", "..", "configs", "config.json")
|
||||
templateHTMLPath := filepath.Join(cwd, "..", "..", "templates", "html")
|
||||
templateMailPath := filepath.Join(cwd, "..", "..", "templates", "email")
|
||||
|
||||
if err := os.Setenv("TEMPLATE_MAIL_PATH", templateMailPath); err != nil {
|
||||
log.Fatalf("Error setting environment variable: %v", err)
|
||||
}
|
||||
if err := os.Setenv("TEMPLATE_HTML_PATH", templateHTMLPath); err != nil {
|
||||
log.Fatalf("Error setting environment variable: %v", err)
|
||||
}
|
||||
if err := os.Setenv("CONFIG_FILE_PATH", configFilePath); err != nil {
|
||||
log.Fatalf("Error setting environment variable: %v", err)
|
||||
}
|
||||
config.LoadConfig()
|
||||
logger.Info.Printf("Config: %#v", config.CFG)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
setupAuth func(r *http.Request)
|
||||
@@ -31,15 +56,15 @@ func TestAuthMiddleware(t *testing.T) {
|
||||
expectedUserID: 123,
|
||||
},
|
||||
{
|
||||
name: "Missing Auth Header",
|
||||
name: "Missing Cookie",
|
||||
setupAuth: func(r *http.Request) {},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedUserID: 0,
|
||||
},
|
||||
{
|
||||
name: "Invalid Token Format",
|
||||
name: "Invalid Token",
|
||||
setupAuth: func(r *http.Request) {
|
||||
r.Header.Set("Authorization", "InvalidFormat")
|
||||
r.AddCookie(&http.Cookie{Name: "jwt", Value: "InvalidToken"})
|
||||
},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedUserID: 0,
|
||||
@@ -48,7 +73,7 @@ func TestAuthMiddleware(t *testing.T) {
|
||||
name: "Expired Token",
|
||||
setupAuth: func(r *http.Request) {
|
||||
token := jwt.NewWithClaims(jwtSigningMethod, jwt.MapClaims{
|
||||
"user_id": "user123",
|
||||
"user_id": 123,
|
||||
"exp": time.Now().Add(-time.Hour).Unix(), // Expired 1 hour ago
|
||||
})
|
||||
tokenString, _ := token.SignedString(jwtKey)
|
||||
@@ -61,7 +86,7 @@ func TestAuthMiddleware(t *testing.T) {
|
||||
name: "Invalid Signature",
|
||||
setupAuth: func(r *http.Request) {
|
||||
token := jwt.NewWithClaims(jwtSigningMethod, jwt.MapClaims{
|
||||
"user_id": "user123",
|
||||
"user_id": 123,
|
||||
"exp": time.Now().Add(time.Hour).Unix(),
|
||||
})
|
||||
tokenString, _ := token.SignedString([]byte("wrong_secret"))
|
||||
@@ -70,6 +95,19 @@ func TestAuthMiddleware(t *testing.T) {
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedUserID: 0,
|
||||
},
|
||||
{
|
||||
name: "Invalid Signing Method",
|
||||
setupAuth: func(r *http.Request) {
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodES256, jwt.MapClaims{
|
||||
"user_id": 123,
|
||||
"exp": time.Now().Add(time.Hour).Unix(),
|
||||
})
|
||||
tokenString, _ := token.SignedString([]byte(config.Auth.JWTSecret))
|
||||
r.AddCookie(&http.Cookie{Name: "jwt", Value: tokenString})
|
||||
},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedUserID: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user