diff --git a/internal/subscriptions/subscriptions.go b/internal/subscriptions/subscriptions.go new file mode 100644 index 000000000..90d5609a5 --- /dev/null +++ b/internal/subscriptions/subscriptions.go @@ -0,0 +1,61 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// 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 . + +package subscriptions + +import ( + "context" + + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" +) + +type Subscriptions struct { + state *state.State +} + +func (s *Subscriptions) UpdateDomainPermissions( + ctx context.Context, + permType gtsmodel.DomainPermissionType, +) { + l := log. + WithContext(ctx). + WithField("permType", permType.String()) + l.Info("start") + + // Get permission subscriptions in priority order (highest -> lowest). + permSubs, err := s.state.DB.GetDomainPermissionSubscriptionsByPriority(ctx, permType) + if err != nil { + l.Error(err) + return + } + + if len(permSubs) == 0 { + // Nothing to do. + return + } + + for i, permSub := range permSubs { + + // Slice of permission subscriptions that + // have a higher priority than this one. + higherPrios := permSubs[:i] + + + } +} diff --git a/internal/transport/derefdomainpermlist.go b/internal/transport/derefdomainpermlist.go new file mode 100644 index 000000000..045c69a26 --- /dev/null +++ b/internal/transport/derefdomainpermlist.go @@ -0,0 +1,99 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// 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 . + +package transport + +import ( + "context" + "io" + "net/http" + + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +) + +type DomainPermissionsRespRaw struct { + body []byte +} + +func (t *transport) DereferenceDomainPermissions( + ctx context.Context, + permSub *gtsmodel.DomainPermissionSubscription, + useCacheHeaders bool, +) (*DomainPermissionsRespRaw, error) { + // Prepare new HTTP request to endpoint + req, err := http.NewRequestWithContext(ctx, "GET", permSub.URI, nil) + if err != nil { + return nil, err + } + + // Set basic auth header if necessary. + if permSub.FetchUsername != "" || permSub.FetchPassword != "" { + req.SetBasicAuth(permSub.FetchUsername, permSub.FetchPassword) + } + + // Set relevant Accept headers. + // Allow fallback in case target doesn't + // negotiate content type correctly. + req.Header.Add("Accept-Charset", "utf-8") + req.Header.Add("Accept", permSub.ContentType.String()+","+"*/*") + + if useCacheHeaders { + // If we've successfully fetched this list + // before, set If-Modified-Since to last + // success to make the request conditional. + // + // See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since + if !permSub.SuccessfullyFetchedAt.IsZero() { + timeStr := permSub.SuccessfullyFetchedAt.Format(http.TimeFormat) + req.Header.Add("If-Modified-Since", timeStr) + } + + // If we've got an ETag stored for this list, set + // If-None-Match to make the request conditional. + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#caching_of_unchanged_resources. + if len(permSub.ETag) != 0 { + req.Header.Add("If-None-Match", permSub.ETag) + } + } + + // Perform the HTTP request + rsp, err := t.GET(req) + if err != nil { + return nil, err + } + defer rsp.Body.Close() + + // Read the body regardless of response code, + // as we may want to store any error message. + bytes, err := io.ReadAll(rsp.Body) + if err != nil { + return nil, err + } + + if rsp.StatusCode == http.StatusNotModified { + // Nothing has changed on the remote side since + // we last fetched, so there's nothing to do. + return nil, nil + } + + // Ensure a non-error status response. + if rsp.StatusCode != http.StatusOK { + err := gtserror.NewFromResponse(rsp) + return nil, err + } +}