package store import ( "context" "atlas9.dev/c/core" "atlas9.dev/c/core/dbi" "atlas9.dev/c/core/iam" "atlas9.dev/c/demo/lib" ) type SqliteUserStore struct { db dbi.DBI guard lib.Guard } var _ iam.UserStore = (*SqliteUserStore)(nil) func NewSqliteUserStore(db dbi.DBI, guard lib.Guard) *SqliteUserStore { return &SqliteUserStore{db: db, guard: guard} } func (s *SqliteUserStore) Save(ctx context.Context, user *iam.User) error { if err := user.Valid(); err != nil { return err } principal := iam.GetPrincipal(ctx) if user.ID.String() != principal.Subject { if err := s.guard.System(ctx, iam.CapUsersSave); err != nil { return err } } _, err := s.db.Exec(ctx, ` INSERT INTO users (id, email, verified) VALUES ($1, $2, $3) ON CONFLICT (email) DO UPDATE SET verified = $3 `, user.ID, user.Email, user.Verified) return err } func (s *SqliteUserStore) GetByEmail(ctx context.Context, email string, out *iam.User) error { if err := s.guard.System(ctx, iam.CapUsersGetByEmail); err != nil { return err } return dbi.Get(ctx, s.db, out, `SELECT id, email, verified FROM users WHERE email = $1`, email) } func (s *SqliteUserStore) Get(ctx context.Context, id core.ID, out *iam.User) error { principal := iam.GetPrincipal(ctx) if id.String() != principal.Subject { if err := s.guard.System(ctx, iam.CapUsersGet); err != nil { return err } } return dbi.Get(ctx, s.db, out, `SELECT id, email, verified FROM users WHERE id = $1`, id) } func (s *SqliteUserStore) Verify(ctx context.Context, id core.ID) error { if err := s.guard.System(ctx, iam.CapUsersVerify); err != nil { return err } _, err := s.db.Exec(ctx, `UPDATE users SET verified = true WHERE id = $1`, id) return err } func (s *SqliteUserStore) List(ctx context.Context, page core.PageReq, out *core.Page[iam.User]) error { if err := s.guard.System(ctx, iam.CapUsersList); err != nil { return err } return dbi.Paginate(ctx, s.db, page, out, func(u iam.User) string { return u.ID.String() }, `SELECT id, email, verified FROM users WHERE id > $cursor ORDER BY id LIMIT $limit`) }