147 lines
3.4 KiB
Go
147 lines
3.4 KiB
Go
// SPDX-License-Identifier: MIT
|
|
|
|
package sqlite
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"github.com/friendsofgo/errors"
|
|
"github.com/mattn/go-sqlite3"
|
|
"github.com/volatiletech/sqlboiler/v4/boil"
|
|
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
|
|
|
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb"
|
|
"github.com/ssb-ngi-pointer/go-ssb-room/roomdb/sqlite/models"
|
|
refs "go.mindeco.de/ssb-refs"
|
|
)
|
|
|
|
// compiler assertion to ensure the struct fullfills the interface
|
|
var _ roomdb.AllowListService = (*AllowList)(nil)
|
|
|
|
type AllowList struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
// Add adds the feed to the list.
|
|
func (l AllowList) Add(ctx context.Context, a refs.FeedRef) error {
|
|
// single insert transaction but this makes it easier to re-use in invites.Consume
|
|
return transact(l.db, func(tx *sql.Tx) error {
|
|
return l.add(ctx, tx, a)
|
|
})
|
|
}
|
|
|
|
// this add is not exported and for internal use with transactions.
|
|
func (l AllowList) add(ctx context.Context, tx *sql.Tx, a refs.FeedRef) error {
|
|
// TODO: better valid
|
|
if _, err := refs.ParseFeedRef(a.Ref()); err != nil {
|
|
return err
|
|
}
|
|
|
|
var entry models.AllowList
|
|
|
|
entry.PubKey.FeedRef = a
|
|
err := entry.Insert(ctx, tx, boil.Whitelist("pub_key"))
|
|
if err != nil {
|
|
var sqlErr sqlite3.Error
|
|
if errors.As(err, &sqlErr) && sqlErr.ExtendedCode == sqlite3.ErrConstraintUnique {
|
|
return roomdb.ErrAlreadyAdded{Ref: a}
|
|
}
|
|
|
|
return fmt.Errorf("allow-list: failed to insert new entry %s: %w - type:%T", entry.PubKey, err, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HasFeed returns true if a feed is on the list.
|
|
func (l AllowList) HasFeed(ctx context.Context, h refs.FeedRef) bool {
|
|
_, err := models.AllowLists(qm.Where("pub_key = ?", h.Ref())).One(ctx, l.db)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// HasID returns true if a feed is on the list.
|
|
func (l AllowList) HasID(ctx context.Context, id int64) bool {
|
|
_, err := models.FindAllowList(ctx, l.db, id)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// GetByID returns the entry if a feed with that ID is on the list.
|
|
func (l AllowList) GetByID(ctx context.Context, id int64) (roomdb.ListEntry, error) {
|
|
var le roomdb.ListEntry
|
|
entry, err := models.FindAllowList(ctx, l.db, id)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return le, roomdb.ErrNotFound
|
|
}
|
|
return le, err
|
|
}
|
|
|
|
le.ID = entry.ID
|
|
le.PubKey = entry.PubKey.FeedRef
|
|
|
|
return le, nil
|
|
}
|
|
|
|
// List returns a list of all the feeds.
|
|
func (l AllowList) List(ctx context.Context) (roomdb.ListEntries, error) {
|
|
all, err := models.AllowLists().All(ctx, l.db)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var asRefs = make(roomdb.ListEntries, len(all))
|
|
for i, allowed := range all {
|
|
|
|
asRefs[i] = roomdb.ListEntry{
|
|
ID: allowed.ID,
|
|
PubKey: allowed.PubKey.FeedRef,
|
|
}
|
|
}
|
|
|
|
return asRefs, nil
|
|
}
|
|
|
|
// RemoveFeed removes the feed from the list.
|
|
func (l AllowList) RemoveFeed(ctx context.Context, r refs.FeedRef) error {
|
|
entry, err := models.AllowLists(qm.Where("pub_key = ?", r.Ref())).One(ctx, l.db)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return roomdb.ErrNotFound
|
|
}
|
|
return err
|
|
}
|
|
|
|
_, err = entry.Delete(ctx, l.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveID removes the feed from the list.
|
|
func (l AllowList) RemoveID(ctx context.Context, id int64) error {
|
|
entry, err := models.FindAllowList(ctx, l.db, id)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return roomdb.ErrNotFound
|
|
}
|
|
return err
|
|
}
|
|
|
|
_, err = entry.Delete(ctx, l.db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|