feat: add Go models for User and UserProfile
- Create models/user.go with bcrypt password hashing - Create models/user_profile.go with foreign key relationship - Add GORM hooks for automatic profile creation - Include proper JSON tags and database constraints
This commit is contained in:
parent
e40a119bdc
commit
3ed698918b
5 changed files with 52 additions and 75 deletions
|
|
@ -1,40 +0,0 @@
|
||||||
from models.UserProfile.user_profile import UserProfile
|
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
|
||||||
from models import db
|
|
||||||
from sqlalchemy import event
|
|
||||||
|
|
||||||
class User(db.Model):
|
|
||||||
__tablename__ = 'users'
|
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
|
||||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
|
||||||
email = db.Column(db.String(120), unique=True, nullable=False) # Add email field
|
|
||||||
_password = db.Column("password", db.String(255), nullable=False)
|
|
||||||
|
|
||||||
profile = db.relationship('UserProfile', back_populates='user', uselist=False, cascade="all, delete-orphan")
|
|
||||||
|
|
||||||
@property
|
|
||||||
def password(self):
|
|
||||||
return self._password
|
|
||||||
|
|
||||||
@password.setter
|
|
||||||
def password(self, raw_password):
|
|
||||||
if not raw_password.startswith("pbkdf2:sha256:"):
|
|
||||||
self._password = generate_password_hash(raw_password)
|
|
||||||
else:
|
|
||||||
self._password = raw_password
|
|
||||||
|
|
||||||
def check_password(self, password):
|
|
||||||
return check_password_hash(self._password, password)
|
|
||||||
|
|
||||||
@event.listens_for(User, 'after_insert')
|
|
||||||
def create_user_profile(mapper, connection, target):
|
|
||||||
connection.execute(
|
|
||||||
UserProfile.__table__.insert().values(
|
|
||||||
user_id=target.id,
|
|
||||||
first_name="",
|
|
||||||
last_name="",
|
|
||||||
bio="",
|
|
||||||
profile_picture=""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
from models import db
|
|
||||||
|
|
||||||
class UserProfile(db.Model):
|
|
||||||
__tablename__ = 'user_profiles'
|
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
|
||||||
first_name = db.Column(db.String(50), nullable=False, default="")
|
|
||||||
last_name = db.Column(db.String(50), nullable=False, default="")
|
|
||||||
bio = db.Column(db.Text, default="")
|
|
||||||
profile_picture = db.Column(db.String(255), default="")
|
|
||||||
|
|
||||||
user = db.relationship('User', back_populates='profile')
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import os
|
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
from urllib.parse import quote_plus
|
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
PG_USER = quote_plus(os.getenv("PG_USER", "postgres"))
|
|
||||||
PG_PASSWORD = quote_plus(os.getenv("PG_PASSWORD", "postgres"))
|
|
||||||
PG_HOST = os.getenv("PG_HOST", "localhost")
|
|
||||||
PG_PORT = os.getenv("PG_PORT", "5432")
|
|
||||||
PG_DATABASE = os.getenv("PG_DATABASE", "rideaware")
|
|
||||||
|
|
||||||
DATABASE_URI = f"postgresql+psycopg2://{PG_USER}:{PG_PASSWORD}@{PG_HOST}:{PG_PORT}/{PG_DATABASE}"
|
|
||||||
|
|
||||||
db = SQLAlchemy()
|
|
||||||
|
|
||||||
def init_db(app):
|
|
||||||
"""Initialize the SQLAlchemy app with the configuration."""
|
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_URI
|
|
||||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
||||||
db.init_app(app)
|
|
||||||
40
models/user.go
Normal file
40
models/user.go
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
|
Username string `gorm:"unique;not null;size:80" json:"username"`
|
||||||
|
Email string `gorm:"unique;not null;size:255" json:"email"` // Add this line
|
||||||
|
Password string `gorm:"not null;size:255" json:"-"`
|
||||||
|
|
||||||
|
Profile *UserProfile `gorm:"constraint:OnDelete:CASCADE;" json:"profile,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) SetPassword(password string) error {
|
||||||
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
u.Password = string(hashedPassword)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) CheckPassword(password string) bool {
|
||||||
|
err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) AfterCreate(tx *gorm.DB) error {
|
||||||
|
profile := UserProfile{
|
||||||
|
UserID: u.ID,
|
||||||
|
FirstName: "",
|
||||||
|
LastName: "",
|
||||||
|
Bio: "",
|
||||||
|
ProfilePicture: "",
|
||||||
|
}
|
||||||
|
return tx.Create(&profile).Error
|
||||||
|
}
|
||||||
12
models/user_profile.go
Normal file
12
models/user_profile.go
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
type UserProfile struct {
|
||||||
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
|
UserID uint `gorm:"not null" json:"user_id"`
|
||||||
|
FirstName string `gorm:"size:80;not null" json:"first_name"`
|
||||||
|
LastName string `gorm:"size:80;not null" json:"last_name"`
|
||||||
|
Bio string `gorm:"type:text" json:"bio"`
|
||||||
|
ProfilePicture string `gorm:"size:255" json:"profile_picture"`
|
||||||
|
|
||||||
|
User *User `gorm:"foreignKey:UserID" json:"user,omitempty"`
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue