Compare commits

..

5 Commits

Author SHA1 Message Date
$(pass /github/name)
82413499f5 add: Admin creation 2024-09-06 09:26:15 +02:00
$(pass /github/name)
df82782ba5 add: auth_test cases & null attack test 2024-09-06 09:22:37 +02:00
$(pass /github/name)
b42713b108 Del old sql schema 2024-09-06 09:21:50 +02:00
$(pass /github/name)
0d7c5674da chg testcases to be private 2024-09-06 09:21:30 +02:00
$(pass /github/name)
46e09a1285 moved admin mail config location 2024-09-06 09:20:55 +02:00
9 changed files with 104 additions and 132 deletions

View File

@@ -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": {

View File

@@ -33,7 +33,6 @@ 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"`
}
@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
);

View File

@@ -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 {