lens @ 8eeddc0bfb574aada6bb76638957421b52344bb0

  1package sql
  2
  3import (
  4	"context"
  5
  6	"golang.org/x/crypto/bcrypt"
  7	"gorm.io/gorm"
  8
  9	"git.sr.ht/~gabrielgio/img/pkg/components/auth"
 10	user "git.sr.ht/~gabrielgio/img/pkg/components/auth"
 11)
 12
 13type (
 14	User struct {
 15		gorm.Model
 16		Username string
 17		Name     string
 18		Password string
 19	}
 20
 21	Users []*User
 22
 23	UserRepository struct {
 24		db *gorm.DB
 25	}
 26)
 27
 28var _ auth.Repository = &UserRepository{}
 29
 30func NewUserRepository(db *gorm.DB) *UserRepository {
 31	return &UserRepository{
 32		db: db,
 33	}
 34}
 35
 36func (self *User) ToModel() *user.User {
 37	return &user.User{
 38		ID:       self.Model.ID,
 39		Name:     self.Name,
 40		Username: self.Username,
 41	}
 42}
 43
 44func (self Users) ToModel() (users []*user.User) {
 45	for _, user := range self {
 46		users = append(users, user.ToModel())
 47	}
 48	return
 49}
 50
 51// Testing function, will remove later
 52// TODO: remove later
 53func (self *UserRepository) EnsureAdmin(ctx context.Context) {
 54	var exists bool
 55	self.db.
 56		WithContext(ctx).
 57		Model(&User{}).
 58		Select("count(*) > 0").
 59		Where("username = ?", "admin").
 60		Find(&exists)
 61
 62	if !exists {
 63		hash, _ := bcrypt.GenerateFromPassword([]byte("admin"), bcrypt.MinCost)
 64		self.db.Save(&User{
 65			Username: "admin",
 66			Password: string(hash),
 67		})
 68	}
 69}
 70
 71func (self *UserRepository) List(ctx context.Context) ([]*user.User, error) {
 72	users := Users{}
 73	result := self.db.
 74		WithContext(ctx).
 75		Find(&users)
 76
 77	if result.Error != nil {
 78		return nil, result.Error
 79	}
 80
 81	return users.ToModel(), nil
 82}
 83
 84func (self *UserRepository) Get(ctx context.Context, id uint) (*user.User, error) {
 85	var user = &user.User{ID: id}
 86	result := self.db.
 87		WithContext(ctx).
 88		First(user)
 89
 90	if result.Error != nil {
 91		return nil, result.Error
 92	}
 93
 94	return user, nil
 95}
 96
 97func (self *UserRepository) GetIDByUsername(ctx context.Context, username string) (uint, error) {
 98	userID := struct {
 99		ID uint
100	}{}
101
102	result := self.db.
103		WithContext(ctx).
104		Model(&User{}).
105		Where("username = ?", username).
106		First(&userID)
107
108	if result.Error != nil {
109		return 0, result.Error
110	}
111
112	return userID.ID, nil
113}
114
115func (self *UserRepository) GetPassword(ctx context.Context, id uint) ([]byte, error) {
116	userPassword := struct {
117		Password []byte
118	}{}
119
120	result := self.db.
121		WithContext(ctx).
122		Model(&User{}).
123		Where("id = ?", id).
124		First(&userPassword)
125
126	if result.Error != nil {
127		return nil, result.Error
128	}
129
130	return userPassword.Password, nil
131}
132
133func (self *UserRepository) Create(ctx context.Context, createUser *user.CreateUser) (uint, error) {
134	user := &User{
135		Username: createUser.Username,
136		Name:     createUser.Name,
137		Password: string(createUser.Password),
138	}
139
140	result := self.db.
141		WithContext(ctx).
142		Create(user)
143	if result.Error != nil {
144		return 0, result.Error
145	}
146
147	return user.Model.ID, nil
148}
149
150func (self *UserRepository) Update(ctx context.Context, id uint, update *user.UpdateUser) error {
151	user := &User{
152		Model: gorm.Model{
153			ID: id,
154		},
155		Username: update.Username,
156		Name:     update.Name,
157	}
158
159	result := self.db.
160		WithContext(ctx).
161		Save(user)
162	if result.Error != nil {
163		return result.Error
164	}
165
166	return nil
167}
168
169func (self *UserRepository) Delete(ctx context.Context, id uint) error {
170	userID := struct {
171		ID uint
172	}{
173		ID: id,
174	}
175	result := self.db.
176		WithContext(ctx).
177		Delete(userID)
178	if result.Error != nil {
179		return result.Error
180	}
181	return nil
182}