Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Create/update/remove domain permission subscriptions #3623

Merged
merged 13 commits into from
Jan 5, 2025
Merged
423 changes: 423 additions & 0 deletions docs/api/swagger.yaml

Large diffs are not rendered by default.

86 changes: 49 additions & 37 deletions internal/api/client/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,47 @@ import (
)

const (
BasePath = "/v1/admin"
EmojiPath = BasePath + "/custom_emojis"
EmojiPathWithID = EmojiPath + "/:" + apiutil.IDKey
EmojiCategoriesPath = EmojiPath + "/categories"
DomainBlocksPath = BasePath + "/domain_blocks"
DomainBlocksPathWithID = DomainBlocksPath + "/:" + apiutil.IDKey
DomainAllowsPath = BasePath + "/domain_allows"
DomainAllowsPathWithID = DomainAllowsPath + "/:" + apiutil.IDKey
DomainPermissionDraftsPath = BasePath + "/domain_permission_drafts"
DomainPermissionDraftsPathWithID = DomainPermissionDraftsPath + "/:" + apiutil.IDKey
DomainPermissionDraftAcceptPath = DomainPermissionDraftsPathWithID + "/accept"
DomainPermissionDraftRemovePath = DomainPermissionDraftsPathWithID + "/remove"
DomainPermissionExcludesPath = BasePath + "/domain_permission_excludes"
DomainPermissionExcludesPathWithID = DomainPermissionExcludesPath + "/:" + apiutil.IDKey
DomainKeysExpirePath = BasePath + "/domain_keys_expire"
HeaderAllowsPath = BasePath + "/header_allows"
HeaderAllowsPathWithID = HeaderAllowsPath + "/:" + apiutil.IDKey
HeaderBlocksPath = BasePath + "/header_blocks"
HeaderBlocksPathWithID = HeaderBlocksPath + "/:" + apiutil.IDKey
AccountsV1Path = BasePath + "/accounts"
AccountsV2Path = "/v2/admin/accounts"
AccountsPathWithID = AccountsV1Path + "/:" + apiutil.IDKey
AccountsActionPath = AccountsPathWithID + "/action"
AccountsApprovePath = AccountsPathWithID + "/approve"
AccountsRejectPath = AccountsPathWithID + "/reject"
MediaCleanupPath = BasePath + "/media_cleanup"
MediaRefetchPath = BasePath + "/media_refetch"
ReportsPath = BasePath + "/reports"
ReportsPathWithID = ReportsPath + "/:" + apiutil.IDKey
ReportsResolvePath = ReportsPathWithID + "/resolve"
EmailPath = BasePath + "/email"
EmailTestPath = EmailPath + "/test"
InstanceRulesPath = BasePath + "/instance/rules"
InstanceRulesPathWithID = InstanceRulesPath + "/:" + apiutil.IDKey
DebugPath = BasePath + "/debug"
DebugAPUrlPath = DebugPath + "/apurl"
DebugClearCachesPath = DebugPath + "/caches/clear"
BasePath = "/v1/admin"
EmojiPath = BasePath + "/custom_emojis"
EmojiPathWithID = EmojiPath + "/:" + apiutil.IDKey
EmojiCategoriesPath = EmojiPath + "/categories"
DomainBlocksPath = BasePath + "/domain_blocks"
DomainBlocksPathWithID = DomainBlocksPath + "/:" + apiutil.IDKey
DomainAllowsPath = BasePath + "/domain_allows"
DomainAllowsPathWithID = DomainAllowsPath + "/:" + apiutil.IDKey
DomainPermissionDraftsPath = BasePath + "/domain_permission_drafts"
DomainPermissionDraftsPathWithID = DomainPermissionDraftsPath + "/:" + apiutil.IDKey
DomainPermissionDraftAcceptPath = DomainPermissionDraftsPathWithID + "/accept"
DomainPermissionDraftRemovePath = DomainPermissionDraftsPathWithID + "/remove"
DomainPermissionExcludesPath = BasePath + "/domain_permission_excludes"
DomainPermissionExcludesPathWithID = DomainPermissionExcludesPath + "/:" + apiutil.IDKey
DomainPermissionSubscriptionsPath = BasePath + "/domain_permission_subscriptions"
DomainPermissionSubscriptionsPathWithID = DomainPermissionSubscriptionsPath + "/:" + apiutil.IDKey
DomainPermissionSubscriptionsPreviewPath = DomainPermissionSubscriptionsPath + "/preview"
DomainPermissionSubscriptionRemovePath = DomainPermissionSubscriptionsPathWithID + "/remove"
DomainKeysExpirePath = BasePath + "/domain_keys_expire"
HeaderAllowsPath = BasePath + "/header_allows"
HeaderAllowsPathWithID = HeaderAllowsPath + "/:" + apiutil.IDKey
HeaderBlocksPath = BasePath + "/header_blocks"
HeaderBlocksPathWithID = HeaderBlocksPath + "/:" + apiutil.IDKey
AccountsV1Path = BasePath + "/accounts"
AccountsV2Path = "/v2/admin/accounts"
AccountsPathWithID = AccountsV1Path + "/:" + apiutil.IDKey
AccountsActionPath = AccountsPathWithID + "/action"
AccountsApprovePath = AccountsPathWithID + "/approve"
AccountsRejectPath = AccountsPathWithID + "/reject"
MediaCleanupPath = BasePath + "/media_cleanup"
MediaRefetchPath = BasePath + "/media_refetch"
ReportsPath = BasePath + "/reports"
ReportsPathWithID = ReportsPath + "/:" + apiutil.IDKey
ReportsResolvePath = ReportsPathWithID + "/resolve"
EmailPath = BasePath + "/email"
EmailTestPath = EmailPath + "/test"
InstanceRulesPath = BasePath + "/instance/rules"
InstanceRulesPathWithID = InstanceRulesPath + "/:" + apiutil.IDKey
DebugPath = BasePath + "/debug"
DebugAPUrlPath = DebugPath + "/apurl"
DebugClearCachesPath = DebugPath + "/caches/clear"

FilterQueryKey = "filter"
MaxShortcodeDomainKey = "max_shortcode_domain"
Expand Down Expand Up @@ -118,6 +122,14 @@ func (m *Module) Route(attachHandler func(method string, path string, f ...gin.H
attachHandler(http.MethodGet, DomainPermissionExcludesPathWithID, m.DomainPermissionExcludeGETHandler)
attachHandler(http.MethodDelete, DomainPermissionExcludesPathWithID, m.DomainPermissionExcludeDELETEHandler)

// domain permission subscriptions stuff
attachHandler(http.MethodPost, DomainPermissionSubscriptionsPath, m.DomainPermissionSubscriptionPOSTHandler)
attachHandler(http.MethodGet, DomainPermissionSubscriptionsPath, m.DomainPermissionSubscriptionsGETHandler)
attachHandler(http.MethodGet, DomainPermissionSubscriptionsPreviewPath, m.DomainPermissionSubscriptionsPreviewGETHandler)
attachHandler(http.MethodGet, DomainPermissionSubscriptionsPathWithID, m.DomainPermissionSubscriptionGETHandler)
attachHandler(http.MethodPatch, DomainPermissionSubscriptionsPathWithID, m.DomainPermissionSubscriptionPATCHHandler)
attachHandler(http.MethodPost, DomainPermissionSubscriptionRemovePath, m.DomainPermissionSubscriptionRemovePOSTHandler)

// header filtering administration routes
attachHandler(http.MethodGet, HeaderAllowsPathWithID, m.HeaderFilterAllowGET)
attachHandler(http.MethodGet, HeaderBlocksPathWithID, m.HeaderFilterBlockGET)
Expand Down
42 changes: 42 additions & 0 deletions internal/api/client/admin/domainpermission.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,45 @@ func (m *Module) getDomainPermissions(

apiutil.JSON(c, http.StatusOK, domainPerm)
}

// parseDomainPermissionType is a util function to parse i
// to a DomainPermissionType, or return a suitable error.
func parseDomainPermissionType(i string) (
permType gtsmodel.DomainPermissionType,
errWithCode gtserror.WithCode,
) {
if i == "" {
const errText = "permission_type not set, must be one of block or allow"
errWithCode = gtserror.NewErrorBadRequest(errors.New(errText), errText)
return
}

permType = gtsmodel.ParseDomainPermissionType(i)
if permType == gtsmodel.DomainPermissionUnknown {
var errText = fmt.Sprintf("permission_type %s not recognized, must be one of block or allow", i)
errWithCode = gtserror.NewErrorBadRequest(errors.New(errText), errText)
}

return
}

// parseDomainPermSubContentType is a util function to parse i
// to a DomainPermSubContentType, or return a suitable error.
func parseDomainPermSubContentType(i string) (
contentType gtsmodel.DomainPermSubContentType,
errWithCode gtserror.WithCode,
) {
if i == "" {
const errText = "content_type not set, must be one of text/csv, text/plain or application/json"
errWithCode = gtserror.NewErrorBadRequest(errors.New(errText), errText)
return
}

contentType = gtsmodel.NewDomainPermSubContentType(i)
if contentType == gtsmodel.DomainPermSubContentTypeUnknown {
var errText = fmt.Sprintf("content_type %s not recognized, must be one of text/csv, text/plain or application/json", i)
errWithCode = gtserror.NewErrorBadRequest(errors.New(errText), errText)
}

return
}
21 changes: 2 additions & 19 deletions internal/api/client/admin/domainpermissiondraftcreate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)

Expand Down Expand Up @@ -136,24 +135,8 @@ func (m *Module) DomainPermissionDraftsPOSTHandler(c *gin.Context) {
return
}

var (
permType gtsmodel.DomainPermissionType
errText string
)

switch pt := form.PermissionType; pt {
case "block":
permType = gtsmodel.DomainPermissionBlock
case "allow":
permType = gtsmodel.DomainPermissionAllow
case "":
errText = "permission_type not set, must be one of block or allow"
default:
errText = fmt.Sprintf("permission_type %s not recognized, must be one of block or allow", pt)
}

if errText != "" {
errWithCode := gtserror.NewErrorBadRequest(errors.New(errText), errText)
permType, errWithCode := parseDomainPermissionType(form.PermissionType)
if errWithCode != nil {
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
return
}
Expand Down
2 changes: 1 addition & 1 deletion internal/api/client/admin/domainpermissiondraftsget.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (m *Module) DomainPermissionDraftsGETHandler(c *gin.Context) {

permTypeStr := c.Query(apiutil.DomainPermissionPermTypeKey)
permType := gtsmodel.ParseDomainPermissionType(permTypeStr)
if permType == gtsmodel.DomainPermissionUnknown {
if permTypeStr != "" && permType == gtsmodel.DomainPermissionUnknown {
text := fmt.Sprintf(
"permission_type %s not recognized, valid values are empty string, block, or allow",
permTypeStr,
Expand Down
Loading