mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-17 10:43:01 -06:00
start work on admin domain blocking
This commit is contained in:
parent
cf19aaf0df
commit
c7192c0431
4 changed files with 112 additions and 12 deletions
|
|
@ -29,10 +29,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// BasePath is the base API path for this module
|
||||
// BasePath is the base API path for this module.
|
||||
BasePath = "/api/v1/admin"
|
||||
// EmojiPath is used for posting/deleting custom emojis
|
||||
// EmojiPath is used for posting/deleting custom emojis.
|
||||
EmojiPath = BasePath + "/custom_emojis"
|
||||
// DomainBlocksPath is used for posting domain blocks.
|
||||
DomainBlocksPath = BasePath + "/domain_blocks"
|
||||
)
|
||||
|
||||
// Module implements the ClientAPIModule interface for admin-related actions (reports, emojis, etc)
|
||||
|
|
@ -54,5 +56,6 @@ func New(config *config.Config, processor processing.Processor, log *logrus.Logg
|
|||
// Route attaches all routes from this module to the given router
|
||||
func (m *Module) Route(r router.Router) error {
|
||||
r.AttachHandler(http.MethodPost, EmojiPath, m.emojiCreatePOSTHandler)
|
||||
r.AttachHandler(http.MethodPost, DomainBlocksPath, m.DomainBlocksPOSTHandler)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
59
internal/api/client/admin/domainblock.go
Normal file
59
internal/api/client/admin/domainblock.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
)
|
||||
|
||||
func (m *Module) DomainBlocksPOSTHandler(c *gin.Context) {
|
||||
l := m.log.WithFields(logrus.Fields{
|
||||
"func": "DomainBlocksPOSTHandler",
|
||||
"request_uri": c.Request.RequestURI,
|
||||
"user_agent": c.Request.UserAgent(),
|
||||
"origin_ip": c.ClientIP(),
|
||||
})
|
||||
|
||||
// make sure we're authed with an admin account
|
||||
authed, err := oauth.Authed(c, true, true, true, true)
|
||||
if err != nil {
|
||||
l.Debugf("couldn't auth: %s", err)
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if !authed.User.Admin {
|
||||
l.Debugf("user %s not an admin", authed.User.ID)
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "not an admin"})
|
||||
return
|
||||
}
|
||||
|
||||
// extract the media create form from the request context
|
||||
l.Tracef("parsing request form: %+v", c.Request.Form)
|
||||
form := &model.DomainBlockCreateRequest{}
|
||||
if err := c.ShouldBind(form); err != nil {
|
||||
l.Debugf("error parsing form %+v: %s", c.Request.Form, err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("could not parse form: %s", err)})
|
||||
return
|
||||
}
|
||||
|
||||
// Give the fields on the request form a first pass to make sure the request is superficially valid.
|
||||
l.Tracef("validating form %+v", form)
|
||||
if err := validateCreateDomainBlock(form); err != nil {
|
||||
l.Debugf("error validating form: %s", err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
domainBlock, err := m.processor.AdminDomainBlockCreate(authed, form)
|
||||
if err != nil {
|
||||
l.Debugf("error creating domain block: %s", err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, domainBlock)
|
||||
}
|
||||
42
internal/api/model/domainblock.go
Normal file
42
internal/api/model/domainblock.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package model
|
||||
|
||||
// DomainBlock represents a block on one domain
|
||||
type DomainBlock struct {
|
||||
Domain string `json:"domain"`
|
||||
Obfuscate bool `json:"obfuscate"`
|
||||
PrivateComment string `json:"private_comment"`
|
||||
PublicComment string `json:"public_comment"`
|
||||
SubscriptionID string `json:"subscription_id"`
|
||||
CreatedBy string `json:"created_by"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
}
|
||||
|
||||
// DomainBlockCreateRequest is the form submitted as a POST to /api/v1/admin/domain_blocks to create a new block.
|
||||
type DomainBlockCreateRequest struct {
|
||||
// hostname/domain to block
|
||||
Domain string `form:"domain" json:"domain" xml:"domain" validation:"required"`
|
||||
// whether the domain should be obfuscated when being displayed publicly
|
||||
Obfuscate bool `form:"obfuscate" json:"obfuscate" xml:"obfuscate"`
|
||||
// private comment for other admins on why the domain was blocked
|
||||
PrivateComment string `form:"private_comment" json:"private_comment" xml:"private_comment"`
|
||||
// public comment on the reason for the domain block
|
||||
PublicComment string `form:"public_comment" json:"public_comment" xml:"public_comment"`
|
||||
}
|
||||
|
|
@ -20,13 +20,11 @@ package gtsmodel
|
|||
|
||||
import "time"
|
||||
|
||||
// DomainBlock represents a federation block against a particular domain, of varying severity.
|
||||
// DomainBlock represents a federation block against a particular domain
|
||||
type DomainBlock struct {
|
||||
// ID of this block in the database
|
||||
ID string `pg:"type:CHAR(26),pk,notnull,unique"`
|
||||
// Domain to block. If ANY PART of the candidate domain contains this string, it will be blocked.
|
||||
// For example: 'example.org' also blocks 'gts.example.org'. '.com' blocks *any* '.com' domains.
|
||||
// TODO: implement wildcards here
|
||||
// blocked domain
|
||||
Domain string `pg:",notnull"`
|
||||
// When was this block created
|
||||
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
|
||||
|
|
@ -34,14 +32,12 @@ type DomainBlock struct {
|
|||
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
|
||||
// Account ID of the creator of this block
|
||||
CreatedByAccountID string `pg:"type:CHAR(26),notnull"`
|
||||
// TODO: define this
|
||||
Severity int
|
||||
// Reject media from this domain?
|
||||
RejectMedia bool
|
||||
// Reject reports from this domain?
|
||||
RejectReports bool
|
||||
// Private comment on this block, viewable to admins
|
||||
PrivateComment string
|
||||
// Public comment on this block, viewable (optionally) by everyone
|
||||
PublicComment string
|
||||
// whether the domain name should appear obfuscated when displaying it publicly
|
||||
Obfuscate bool
|
||||
// if this block was created through a subscription, what's the subscription ID?
|
||||
SubscriptionID string `pg:"type:CHAR(26)"`
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue