package models import ( "context" "database/sql" "fmt" "time" "github.com/google/uuid" "github.com/uptrace/bun" ) type UserAttributes struct { Groups []Group `json:"groups"` } type User struct { bun.BaseModel `bun:"table:users"` UserID uuid.UUID `bun:"type:uuid,pk,default:gen_random_uuid()" json:"userId"` FirstName string `bun:"firstname,notnull" json:"firstname"` LastName string `bun:"lastname,notnull" json:"lastname"` Email string `bun:"email,unique,notnull" json:"email"` Password string `bun:"password,notnull" json:"password,omitempty"` Phone string `bun:"phone,notnull" json:"phone"` CreatedAt time.Time `bun:"created_at,default:current_timestamp" json:"createdAt"` UpdatedAt time.Time `bun:"updated_at,default:current_timestamp" json:"updatedAt"` Events []Event `bun:"m2m:events_to_users,join:User=Event" json:"events,omitempty"` Articles []*Blog `bun:"rel:has-many,join:user_id=blog_id" json:"articles,omitempty"` Attributes UserAttributes `bun:"attributes,type:jsonb" json:"attributes"` Roles []Role `bun:"m2m:users_to_roles,join:User=Role" json:"roles,omitempty"` } func (u *User) Insert(db *bun.DB, ctx context.Context) (sql.Result, error) { return db.NewInsert(). Model(u). Value("password", "crypt(?, gen_salt('bf'))", u.Password). Ignore(). // Returning("user_id"). Exec(ctx) } func Verify(db *bun.DB, ctx context.Context, email, password string) (*User, error) { var user User count, err := db.NewSelect(). Model(&user). Where("email = ? AND password = crypt(?, password)", email, password). Limit(1). ScanAndCount(context.Background()) if count == 0 { return nil, fmt.Errorf("invalid email or password") } if err != nil { if err == sql.ErrNoRows { return nil, fmt.Errorf("invalid email or password") } return nil, err } return &user, nil }