120 lines
2.9 KiB
Go
120 lines
2.9 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
libmongo "apps/backend/internal/lib/mongo"
|
|
"apps/backend/internal/module/threads/domain"
|
|
|
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
const (
|
|
colAccounts = "threads_accounts"
|
|
colStates = "threads_oauth_states"
|
|
)
|
|
|
|
// MonStore uses go-zero mon (no entity cache for tokens).
|
|
type MonStore struct {
|
|
accounts *mon.Model
|
|
states *mon.Model
|
|
}
|
|
|
|
func NewMonStore(uri, database string) *MonStore {
|
|
uri = libmongo.MustMongoURI(uri)
|
|
return &MonStore{
|
|
accounts: mon.MustNewModel(uri, database, colAccounts),
|
|
states: mon.MustNewModel(uri, database, colStates),
|
|
}
|
|
}
|
|
|
|
func (s *MonStore) Insert(ctx context.Context, a *domain.Account) error {
|
|
_, err := s.accounts.InsertOne(ctx, a)
|
|
return err
|
|
}
|
|
|
|
func (s *MonStore) Update(ctx context.Context, a *domain.Account) error {
|
|
a.UpdatedAt = domain.NowNano()
|
|
res, err := s.accounts.ReplaceOne(ctx, bson.M{"_id": a.ID}, a)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if res.MatchedCount == 0 {
|
|
return domain.ErrNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *MonStore) FindByID(ctx context.Context, id string) (*domain.Account, error) {
|
|
var a domain.Account
|
|
err := s.accounts.FindOne(ctx, &a, bson.M{"_id": id})
|
|
if err != nil {
|
|
if err == mon.ErrNotFound {
|
|
return nil, domain.ErrNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return &a, nil
|
|
}
|
|
|
|
func (s *MonStore) FindByOwnerAndThreadsUser(ctx context.Context, ownerUID int64, threadsUserID string) (*domain.Account, error) {
|
|
if threadsUserID == "" {
|
|
return nil, domain.ErrNotFound
|
|
}
|
|
var a domain.Account
|
|
err := s.accounts.FindOne(ctx, &a, bson.M{"owner_uid": ownerUID, "threads_user_id": threadsUserID})
|
|
if err != nil {
|
|
if err == mon.ErrNotFound {
|
|
return nil, domain.ErrNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return &a, nil
|
|
}
|
|
|
|
func (s *MonStore) ListByOwner(ctx context.Context, ownerUID int64) ([]*domain.Account, error) {
|
|
var list []*domain.Account
|
|
err := s.accounts.Find(ctx, &list, bson.M{"owner_uid": ownerUID},
|
|
options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}}))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return list, nil
|
|
}
|
|
|
|
func (s *MonStore) Delete(ctx context.Context, id string) error {
|
|
res, err := s.accounts.DeleteOne(ctx, bson.M{"_id": id})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if res == 0 {
|
|
return domain.ErrNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *MonStore) SaveState(ctx context.Context, st *domain.OAuthState) error {
|
|
_, err := s.states.InsertOne(ctx, st)
|
|
return err
|
|
}
|
|
|
|
func (s *MonStore) TakeState(ctx context.Context, state string) (*domain.OAuthState, error) {
|
|
var st domain.OAuthState
|
|
err := s.states.FindOneAndDelete(ctx, &st, bson.M{"_id": state})
|
|
if err != nil {
|
|
if err == mon.ErrNotFound {
|
|
return nil, domain.ErrInvalidState
|
|
}
|
|
return nil, err
|
|
}
|
|
if st.ExpiresAt > 0 && time.Now().UTC().UnixNano() > st.ExpiresAt {
|
|
return nil, domain.ErrInvalidState
|
|
}
|
|
return &st, nil
|
|
}
|
|
|
|
var _ domain.Repository = (*MonStore)(nil)
|