Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions auditlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ const (
AuditActionFeatureFlagToggle AuditActionType = 440
AuditActionFeatureFlagCreate AuditActionType = 441
AuditActionFeatureFlagRulesUpdate AuditActionType = 442

AuditActionSubmissionBlacklistAdd AuditActionType = 450
AuditActionSubmissionBlacklistRemove AuditActionType = 451
)

type AuditCategory int16
Expand Down Expand Up @@ -206,6 +209,7 @@ const (
AuditResourceNotification AuditResourceType = 36
AuditResourceUserEmailVerification AuditResourceType = 37
AuditResourceFeatureFlag AuditResourceType = 38
AuditResourceSubmissionBlacklist AuditResourceType = 39
)

type AuditLogEntry struct {
Expand Down
3 changes: 3 additions & 0 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ type Database struct {
Settings *SettingsTable
Skus *Skus
StaffOverride *StaffOverride
SubmissionBlacklist *SubmissionBlacklist
SubscriptionSkus *SubscriptionSkus
SupportTeam *SupportTeamTable
SupportTeamMembers *SupportTeamMembersTable
Expand Down Expand Up @@ -204,6 +205,7 @@ func NewDatabase(pool *pgxpool.Pool) *Database {
Settings: newSettingsTable(pool),
Skus: newSkusTable(pool),
StaffOverride: newStaffOverride(pool),
SubmissionBlacklist: newSubmissionBlacklist(pool),
SubscriptionSkus: newSubscriptionSkusTable(pool),
SupportTeam: newSupportTeamTable(pool),
SupportTeamMembers: newSupportTeamMembersTable(pool),
Expand Down Expand Up @@ -320,6 +322,7 @@ func (d *Database) CreateTables(ctx context.Context, pool *pgxpool.Pool) {
d.ServerBlacklist,
d.Settings,
d.StaffOverride,
d.SubmissionBlacklist,
d.SupportTeam,
d.SupportTeamMembers,
d.SupportTeamRoles,
Expand Down
2 changes: 2 additions & 0 deletions globalblacklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (b *GlobalBlacklist) ListAll(ctx context.Context) (users []uint64, err erro
if err != nil {
return
}
defer rows.Close()

for rows.Next() {
var userId uint64
Expand All @@ -60,6 +61,7 @@ func (b *GlobalBlacklist) ListAll(ctx context.Context) (users []uint64, err erro
users = append(users, userId)
}

err = rows.Err()
return
}

Expand Down
7 changes: 4 additions & 3 deletions guildpurge.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ var guildPurgeLegacy = []string{

// Guild-scoped but deliberately retained; keeps the drift test honest.
var guildPurgeExempt = map[string]string{
"guild_leave_time": "drives the purge itself; the caller deletes the row once the purge succeeds",
"entitlements": "billing record, retained beyond the guild",
"server_blacklist": "global ban list; purging it would silently un-ban the guild",
"guild_leave_time": "drives the purge itself; the caller deletes the row once the purge succeeds",
"entitlements": "billing record, retained beyond the guild",
"server_blacklist": "global ban list; purging it would silently un-ban the guild",
"submission_blacklist": "gallery ban list; purging it would silently un-ban the guild",
}

// PurgeGuildData deletes all data associated with a guild from all tables.
Expand Down
6 changes: 4 additions & 2 deletions serverblacklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func (b *ServerBlacklist) ListAll(ctx context.Context) ([]uint64, error) {
if err != nil {
return nil, err
}
defer rows.Close()

var guilds []uint64
for rows.Next() {
Expand All @@ -90,7 +91,7 @@ func (b *ServerBlacklist) ListAll(ctx context.Context) ([]uint64, error) {
guilds = append(guilds, guildId)
}

return guilds, nil
return guilds, rows.Err()
}

func (b *ServerBlacklist) Add(ctx context.Context, guildId uint64, reason *string, ownerId *uint64, realOwnerId *uint64) (err error) {
Expand All @@ -110,6 +111,7 @@ func (b *ServerBlacklist) ListAllEntries(ctx context.Context) ([]ServerBlacklist
if err != nil {
return nil, err
}
defer rows.Close()

var entries []ServerBlacklistEntry
for rows.Next() {
Expand All @@ -119,6 +121,6 @@ func (b *ServerBlacklist) ListAllEntries(ctx context.Context) ([]ServerBlacklist
}
entries = append(entries, entry)
}
return entries, nil
return entries, rows.Err()
}

125 changes: 125 additions & 0 deletions submissionblacklist.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package database

import (
"context"
"errors"

"github.com/jackc/pgx/v4"
"github.com/jackc/pgx/v4/pgxpool"
)

type SubmissionFeature string

const (
SubmissionFeatureGallery SubmissionFeature = "gallery"
SubmissionFeatureIntegrations SubmissionFeature = "integrations"
)

type SubmissionTargetType string

const (
SubmissionTargetUser SubmissionTargetType = "user"
SubmissionTargetGuild SubmissionTargetType = "guild"
)

func (f SubmissionFeature) AllowsTarget(t SubmissionTargetType) bool {
switch f {
case SubmissionFeatureGallery:
return t == SubmissionTargetUser || t == SubmissionTargetGuild
case SubmissionFeatureIntegrations:
return t == SubmissionTargetUser
default:
return false
}
}

type SubmissionBlacklistEntry struct {
TargetType SubmissionTargetType
TargetId uint64
Reason *string
}

type SubmissionBlacklist struct {
*pgxpool.Pool
}

func newSubmissionBlacklist(db *pgxpool.Pool) *SubmissionBlacklist {
return &SubmissionBlacklist{
db,
}
}

func (b SubmissionBlacklist) Schema() string {
return `
CREATE TABLE IF NOT EXISTS submission_blacklist(
"feature" TEXT NOT NULL,
"target_type" TEXT NOT NULL,
"target_id" int8 NOT NULL,
"reason" TEXT,
PRIMARY KEY("feature", "target_type", "target_id")
);
`
}

func (b *SubmissionBlacklist) IsBlacklisted(ctx context.Context, feature SubmissionFeature, userId, guildId uint64) (bool, SubmissionTargetType, error) {
query := `
SELECT "target_type" FROM submission_blacklist
WHERE "feature" = $1
AND (("target_type" = 'user' AND "target_id" = $2) OR ("target_type" = 'guild' AND "target_id" = $3))
ORDER BY "target_type" = 'user' DESC
LIMIT 1;
`

var targetType SubmissionTargetType
if err := b.QueryRow(ctx, query, feature, userId, guildId).Scan(&targetType); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return false, "", nil
}
return false, "", err
}

return true, targetType, nil
}

func (b *SubmissionBlacklist) List(ctx context.Context, feature SubmissionFeature) ([]SubmissionBlacklistEntry, error) {
query := `
SELECT "target_type", "target_id", "reason"
FROM submission_blacklist
WHERE "feature" = $1
ORDER BY "target_type", "target_id";
`

rows, err := b.Query(ctx, query, feature)
if err != nil {
return nil, err
}
defer rows.Close()

var entries []SubmissionBlacklistEntry
for rows.Next() {
var entry SubmissionBlacklistEntry
if err := rows.Scan(&entry.TargetType, &entry.TargetId, &entry.Reason); err != nil {
return nil, err
}

entries = append(entries, entry)
}

return entries, rows.Err()
}

func (b *SubmissionBlacklist) Add(ctx context.Context, feature SubmissionFeature, targetType SubmissionTargetType, targetId uint64, reason *string) (err error) {
query := `
INSERT INTO submission_blacklist("feature", "target_type", "target_id", "reason")
VALUES($1, $2, $3, $4)
ON CONFLICT("feature", "target_type", "target_id") DO UPDATE SET "reason" = EXCLUDED."reason";
`

_, err = b.Exec(ctx, query, feature, targetType, targetId, reason)
return
}

func (b *SubmissionBlacklist) Delete(ctx context.Context, feature SubmissionFeature, targetType SubmissionTargetType, targetId uint64) (err error) {
_, err = b.Exec(ctx, `DELETE FROM submission_blacklist WHERE "feature" = $1 AND "target_type" = $2 AND "target_id" = $3;`, feature, targetType, targetId)
return
}
Loading