mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-30 00:36:14 -06:00
[bugfix] More permissive CSV parsing for perm subs, text parse fix
This commit is contained in:
parent
451803b230
commit
b7589324f1
3 changed files with 159 additions and 33 deletions
|
|
@ -39,7 +39,7 @@ type DomainPermissionSubscriptionTestTestSuite struct {
|
||||||
AdminStandardTestSuite
|
AdminStandardTestSuite
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *DomainPermissionSubscriptionTestTestSuite) TestDomainPermissionSubscriptionTest() {
|
func (suite *DomainPermissionSubscriptionTestTestSuite) TestDomainPermissionSubscriptionTestCSV() {
|
||||||
var (
|
var (
|
||||||
ctx = context.Background()
|
ctx = context.Background()
|
||||||
testAccount = suite.testAccounts["admin_account"]
|
testAccount = suite.testAccounts["admin_account"]
|
||||||
|
|
@ -120,6 +120,85 @@ func (suite *DomainPermissionSubscriptionTestTestSuite) TestDomainPermissionSubs
|
||||||
suite.False(blocked)
|
suite.False(blocked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *DomainPermissionSubscriptionTestTestSuite) TestDomainPermissionSubscriptionTestText() {
|
||||||
|
var (
|
||||||
|
ctx = context.Background()
|
||||||
|
testAccount = suite.testAccounts["admin_account"]
|
||||||
|
permSub = >smodel.DomainPermissionSubscription{
|
||||||
|
ID: "01JGE681TQSBPAV59GZXPKE62H",
|
||||||
|
Priority: 255,
|
||||||
|
Title: "whatever!",
|
||||||
|
PermissionType: gtsmodel.DomainPermissionBlock,
|
||||||
|
AsDraft: util.Ptr(false),
|
||||||
|
AdoptOrphans: util.Ptr(true),
|
||||||
|
CreatedByAccountID: testAccount.ID,
|
||||||
|
CreatedByAccount: testAccount,
|
||||||
|
URI: "https://lists.example.org/baddies.txt",
|
||||||
|
ContentType: gtsmodel.DomainPermSubContentTypePlain,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create a subscription for a plaintext list of baddies.
|
||||||
|
err := suite.state.DB.PutDomainPermissionSubscription(ctx, permSub)
|
||||||
|
if err != nil {
|
||||||
|
suite.FailNow(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the request to the /test endpoint.
|
||||||
|
subPath := strings.ReplaceAll(
|
||||||
|
admin.DomainPermissionSubscriptionTestPath,
|
||||||
|
":id", permSub.ID,
|
||||||
|
)
|
||||||
|
path := "/api" + subPath
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
ginCtx := suite.newContext(recorder, http.MethodPost, nil, path, "application/json")
|
||||||
|
ginCtx.Params = gin.Params{
|
||||||
|
gin.Param{
|
||||||
|
Key: apiutil.IDKey,
|
||||||
|
Value: permSub.ID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger the handler.
|
||||||
|
suite.adminModule.DomainPermissionSubscriptionTestPOSTHandler(ginCtx)
|
||||||
|
suite.Equal(http.StatusOK, recorder.Code)
|
||||||
|
|
||||||
|
// Read the body back.
|
||||||
|
b, err := io.ReadAll(recorder.Body)
|
||||||
|
if err != nil {
|
||||||
|
suite.FailNow(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
dst := new(bytes.Buffer)
|
||||||
|
if err := json.Indent(dst, b, "", " "); err != nil {
|
||||||
|
suite.FailNow(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure expected.
|
||||||
|
suite.Equal(`[
|
||||||
|
{
|
||||||
|
"domain": "bumfaces.net"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "peepee.poopoo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "nothanks.com"
|
||||||
|
}
|
||||||
|
]`, dst.String())
|
||||||
|
|
||||||
|
// No permissions should be created
|
||||||
|
// since this is a dry run / test.
|
||||||
|
blocked, err := suite.state.DB.AreDomainsBlocked(
|
||||||
|
ctx,
|
||||||
|
[]string{"bumfaces.net", "peepee.poopoo", "nothanks.com"},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
suite.FailNow(err.Error())
|
||||||
|
}
|
||||||
|
suite.False(blocked)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDomainPermissionSubscriptionTestTestSuite(t *testing.T) {
|
func TestDomainPermissionSubscriptionTestTestSuite(t *testing.T) {
|
||||||
suite.Run(t, &DomainPermissionSubscriptionTestTestSuite{})
|
suite.Run(t, &DomainPermissionSubscriptionTestTestSuite{})
|
||||||
}
|
}
|
||||||
|
|
@ -533,19 +533,60 @@ func permsFromCSV(
|
||||||
return nil, gtserror.NewfAt(3, "error decoding csv column headers: %w", err)
|
return nil, gtserror.NewfAt(3, "error decoding csv column headers: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !slices.Equal(
|
var (
|
||||||
columnHeaders,
|
domainI *int
|
||||||
[]string{
|
severityI *int
|
||||||
"#domain",
|
publicCommentI *int
|
||||||
"#severity",
|
obfuscateI *int
|
||||||
"#reject_media",
|
)
|
||||||
"#reject_reports",
|
|
||||||
"#public_comment",
|
for i, columnHeader := range columnHeaders {
|
||||||
"#obfuscate",
|
// Remove leading # if present.
|
||||||
},
|
normal := strings.TrimLeft(columnHeader, "#")
|
||||||
) {
|
|
||||||
|
// Find index of each column header we
|
||||||
|
// care about, ensuring no duplicates.
|
||||||
|
switch normal {
|
||||||
|
|
||||||
|
case "domain":
|
||||||
|
if domainI != nil {
|
||||||
|
body.Close()
|
||||||
|
err := gtserror.NewfAt(3, "duplicate domain column header in csv: %+v", columnHeaders)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
domainI = &i
|
||||||
|
|
||||||
|
case "severity":
|
||||||
|
if severityI != nil {
|
||||||
|
body.Close()
|
||||||
|
err := gtserror.NewfAt(3, "duplicate severity column header in csv: %+v", columnHeaders)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
severityI = &i
|
||||||
|
|
||||||
|
case "public_comment":
|
||||||
|
if publicCommentI != nil {
|
||||||
|
body.Close()
|
||||||
|
err := gtserror.NewfAt(3, "duplicate public_comment column header in csv: %+v", columnHeaders)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
publicCommentI = &i
|
||||||
|
|
||||||
|
case "obfuscate":
|
||||||
|
if obfuscateI != nil {
|
||||||
|
body.Close()
|
||||||
|
err := gtserror.NewfAt(3, "duplicate obfuscate column header in csv: %+v", columnHeaders)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
obfuscateI = &i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we have at least a domain
|
||||||
|
// index, as that's the bare minimum.
|
||||||
|
if domainI == nil {
|
||||||
body.Close()
|
body.Close()
|
||||||
err := gtserror.NewfAt(3, "unexpected column headers in csv: %+v", columnHeaders)
|
err := gtserror.NewfAt(3, "no domain column header in csv: %+v", columnHeaders)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -576,25 +617,19 @@ func permsFromCSV(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
// Skip records that specify severity
|
||||||
domainRaw = record[0]
|
// that's not "suspend" (we don't support
|
||||||
severity = record[1]
|
// "silence" or "limit" or whatever yet).
|
||||||
publicComment = record[4]
|
if severityI != nil {
|
||||||
obfuscateStr = record[5]
|
severity := record[*severityI]
|
||||||
)
|
if severity != "suspend" {
|
||||||
|
l.Warnf("skipping non-suspend record: %+v", record)
|
||||||
if severity != "suspend" {
|
continue
|
||||||
l.Warnf("skipping non-suspend record: %+v", record)
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
obfuscate, err := strconv.ParseBool(obfuscateStr)
|
|
||||||
if err != nil {
|
|
||||||
l.Warnf("couldn't parse obfuscate field of record: %+v", record)
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize + validate domain.
|
// Normalize + validate domain.
|
||||||
|
domainRaw := record[*domainI]
|
||||||
domain, err := validateDomain(domainRaw)
|
domain, err := validateDomain(domainRaw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Warnf("skipping invalid domain %s: %+v", domainRaw, err)
|
l.Warnf("skipping invalid domain %s: %+v", domainRaw, err)
|
||||||
|
|
@ -611,9 +646,21 @@ func permsFromCSV(
|
||||||
perm = >smodel.DomainAllow{Domain: domain}
|
perm = >smodel.DomainAllow{Domain: domain}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set remaining fields.
|
// Set remaining optional fields
|
||||||
perm.SetPublicComment(publicComment)
|
// if they're present in the CSV.
|
||||||
perm.SetObfuscate(&obfuscate)
|
if publicCommentI != nil {
|
||||||
|
perm.SetPublicComment(record[*publicCommentI])
|
||||||
|
}
|
||||||
|
|
||||||
|
if obfuscateI != nil {
|
||||||
|
obfuscate, err := strconv.ParseBool(record[*obfuscateI])
|
||||||
|
if err != nil {
|
||||||
|
l.Warnf("couldn't parse obfuscate field of record: %+v", record)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
perm.SetObfuscate(&obfuscate)
|
||||||
|
}
|
||||||
|
|
||||||
// We're done.
|
// We're done.
|
||||||
perms = append(perms, perm)
|
perms = append(perms, perm)
|
||||||
|
|
|
||||||
|
|
@ -2115,7 +2115,7 @@ func (c *Converter) DomainPermToAPIDomainPerm(
|
||||||
}
|
}
|
||||||
|
|
||||||
domainPerm.ID = d.GetID()
|
domainPerm.ID = d.GetID()
|
||||||
domainPerm.Obfuscate = *d.GetObfuscate()
|
domainPerm.Obfuscate = util.PtrOrZero(d.GetObfuscate())
|
||||||
domainPerm.PrivateComment = d.GetPrivateComment()
|
domainPerm.PrivateComment = d.GetPrivateComment()
|
||||||
domainPerm.SubscriptionID = d.GetSubscriptionID()
|
domainPerm.SubscriptionID = d.GetSubscriptionID()
|
||||||
domainPerm.CreatedBy = d.GetCreatedByAccountID()
|
domainPerm.CreatedBy = d.GetCreatedByAccountID()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue