lens @ 4d930c0c8cb585979798fac2bb254f991faa62fb

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