169 lines
4.6 KiB
Go
169 lines
4.6 KiB
Go
package repository
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/api/models"
|
|
"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/database"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
// DBUser represents a user from the database
|
|
type DBUser struct {
|
|
UserID int `db:"UserID"`
|
|
UserEmail string `db:"UserEmail"`
|
|
UserPassword string `db:"UserPassword"`
|
|
UserRole string `db:"UserRole"`
|
|
UserName string `db:"UserName"`
|
|
UserCreatedAt time.Time `db:"UserCreatedAt"`
|
|
UserUpdatedAt time.Time `db:"UserUpdatedAt"`
|
|
}
|
|
|
|
// DBRefreshToken represents a refresh token from the database
|
|
type DBRefreshToken struct {
|
|
ID int `db:"id"`
|
|
Token string `db:"token"`
|
|
UserID string `db:"user_id"`
|
|
ExpiresAt time.Time `db:"expires_at"`
|
|
IsRevoked bool `db:"is_revoked"`
|
|
CreatedAt time.Time `db:"created_at"`
|
|
}
|
|
|
|
// UserRepository handles database operations related to users
|
|
type UserRepository struct {
|
|
*Repository
|
|
}
|
|
|
|
// NewUserRepository creates a new user repository
|
|
func NewUserRepository() *UserRepository {
|
|
return &UserRepository{
|
|
Repository: NewRepository(),
|
|
}
|
|
}
|
|
|
|
// ToUser converts a DBUser to a User model
|
|
func (u *DBUser) ToUser() *models.User {
|
|
return &models.User{
|
|
ID: fmt.Sprintf("%d", u.UserID),
|
|
Email: u.UserEmail,
|
|
Password: u.UserPassword,
|
|
Role: u.UserRole,
|
|
Name: u.UserName,
|
|
CreatedAt: u.UserCreatedAt.Format(time.RFC3339),
|
|
UpdatedAt: u.UserUpdatedAt.Format(time.RFC3339),
|
|
}
|
|
}
|
|
|
|
// GetUserByEmail retrieves a user by email
|
|
func (r *UserRepository) GetUserByEmail(email string) (*models.User, error) {
|
|
var dbUser DBUser
|
|
|
|
query := `SELECT * FROM user WHERE UserEmail = ?`
|
|
err := database.DB.Get(&dbUser, query, email)
|
|
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, fmt.Errorf("database error getting user by email: %w", err)
|
|
}
|
|
|
|
return dbUser.ToUser(), nil
|
|
}
|
|
|
|
// GetUserByID retrieves a user by ID
|
|
func (r *UserRepository) GetUserByID(id string) (*models.User, error) {
|
|
var dbUser DBUser
|
|
|
|
query := `SELECT * FROM user WHERE UserID = ?`
|
|
err := database.DB.Get(&dbUser, query, id)
|
|
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, fmt.Errorf("database error getting user by ID: %w", err)
|
|
}
|
|
|
|
return dbUser.ToUser(), nil
|
|
}
|
|
|
|
// StoreRefreshToken saves a refresh token to the database
|
|
func (r *UserRepository) StoreRefreshToken(userID string, token string, expiresAt time.Time) error {
|
|
query := `INSERT INTO refresh_tokens (token, user_id, expires_at, is_revoked, created_at)
|
|
VALUES (?, ?, ?, false, NOW())`
|
|
|
|
_, err := database.DB.Exec(query, token, userID, expiresAt)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("database error storing refresh token: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetRefreshToken retrieves a refresh token from the database
|
|
func (r *UserRepository) GetRefreshToken(token string) (*models.RefreshToken, error) {
|
|
var dbToken DBRefreshToken
|
|
|
|
query := `SELECT * FROM refresh_tokens WHERE token = ?`
|
|
err := database.DB.Get(&dbToken, query, token)
|
|
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return nil, fmt.Errorf("database error getting refresh token: %w", err)
|
|
}
|
|
|
|
return &models.RefreshToken{
|
|
ID: fmt.Sprintf("%d", dbToken.ID),
|
|
UserID: dbToken.UserID,
|
|
Token: dbToken.Token,
|
|
ExpiresAt: dbToken.ExpiresAt.Format(time.RFC3339),
|
|
IsRevoked: dbToken.IsRevoked,
|
|
CreatedAt: dbToken.CreatedAt.Format(time.RFC3339),
|
|
}, nil
|
|
}
|
|
|
|
// RevokeRefreshToken marks a refresh token as revoked
|
|
func (r *UserRepository) RevokeRefreshToken(token string) error {
|
|
query := `UPDATE refresh_tokens SET is_revoked = true WHERE token = ?`
|
|
_, err := database.DB.Exec(query, token)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("database error revoking refresh token: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CreateUser creates a new user
|
|
func (r *UserRepository) CreateUser(user *models.User) error {
|
|
// Hash the password before storing
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to hash password: %w", err)
|
|
}
|
|
|
|
query := `INSERT INTO user (UserEmail, UserPassword, UserRole, UserName, UserCreatedAt, UserUpdatedAt)
|
|
VALUES (?, ?, ?, ?, NOW(), NOW())`
|
|
|
|
result, err := database.DB.Exec(query, user.Email, string(hashedPassword), user.Role, user.Name)
|
|
if err != nil {
|
|
return fmt.Errorf("database error creating user: %w", err)
|
|
}
|
|
|
|
// Get the last inserted ID
|
|
id, err := result.LastInsertId()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get last insert ID: %w", err)
|
|
}
|
|
|
|
// Update the user ID
|
|
user.ID = fmt.Sprintf("%d", id)
|
|
return nil
|
|
}
|