forked from tangled.org/core
this repo has no description

knotserver: add query lexicon for owner

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li 6adfb3a9 4cdc2d84

verified
Changed files
+225 -151
appview
knotserver
spindle
+31
appview/db/db.go
··· 703 703 return err 704 704 }) 705 705 706 + // repurpose the read-only column to "needs-upgrade" 707 + runMigration(conn, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error { 708 + _, err := tx.Exec(` 709 + alter table registrations rename column read_only to needs_upgrade; 710 + `) 711 + return err 712 + }) 713 + 714 + // require all knots to upgrade after the release of total xrpc 715 + runMigration(conn, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error { 716 + _, err := tx.Exec(` 717 + update registrations set needs_upgrade = 1; 718 + `) 719 + return err 720 + }) 721 + 722 + // require all knots to upgrade after the release of total xrpc 723 + runMigration(conn, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error { 724 + _, err := tx.Exec(` 725 + alter table spindles add column needs_upgrade integer not null default 0; 726 + `) 727 + if err != nil { 728 + return err 729 + } 730 + 731 + _, err = tx.Exec(` 732 + update spindles set needs_upgrade = 1; 733 + `) 734 + return err 735 + }) 736 + 706 737 return &DB{db}, nil 707 738 } 708 739
+17 -17
appview/db/registration.go
··· 10 10 // Registration represents a knot registration. Knot would've been a better 11 11 // name but we're stuck with this for historical reasons. 12 12 type Registration struct { 13 - Id int64 14 - Domain string 15 - ByDid string 16 - Created *time.Time 17 - Registered *time.Time 18 - ReadOnly bool 13 + Id int64 14 + Domain string 15 + ByDid string 16 + Created *time.Time 17 + Registered *time.Time 18 + NeedsUpgrade bool 19 19 } 20 20 21 21 func (r *Registration) Status() Status { 22 - if r.ReadOnly { 23 - return ReadOnly 22 + if r.NeedsUpgrade { 23 + return NeedsUpgrade 24 24 } else if r.Registered != nil { 25 25 return Registered 26 26 } else { ··· 32 32 return r.Status() == Registered 33 33 } 34 34 35 - func (r *Registration) IsReadOnly() bool { 36 - return r.Status() == ReadOnly 35 + func (r *Registration) IsNeedsUpgrade() bool { 36 + return r.Status() == NeedsUpgrade 37 37 } 38 38 39 39 func (r *Registration) IsPending() bool { ··· 45 45 const ( 46 46 Registered Status = iota 47 47 Pending 48 - ReadOnly 48 + NeedsUpgrade 49 49 ) 50 50 51 51 func GetRegistrations(e Execer, filters ...filter) ([]Registration, error) { ··· 64 64 } 65 65 66 66 query := fmt.Sprintf(` 67 - select id, domain, did, created, registered, read_only 67 + select id, domain, did, created, registered, needs_upgrade 68 68 from registrations 69 69 %s 70 70 order by created ··· 80 80 for rows.Next() { 81 81 var createdAt string 82 82 var registeredAt sql.Null[string] 83 - var readOnly int 83 + var needsUpgrade int 84 84 var reg Registration 85 85 86 - err = rows.Scan(&reg.Id, &reg.Domain, &reg.ByDid, &createdAt, &registeredAt, &readOnly) 86 + err = rows.Scan(&reg.Id, &reg.Domain, &reg.ByDid, &createdAt, &registeredAt, &needsUpgrade) 87 87 if err != nil { 88 88 return nil, err 89 89 } ··· 98 98 } 99 99 } 100 100 101 - if readOnly != 0 { 102 - reg.ReadOnly = true 101 + if needsUpgrade != 0 { 102 + reg.NeedsUpgrade = true 103 103 } 104 104 105 105 registrations = append(registrations, reg) ··· 116 116 args = append(args, filter.Arg()...) 117 117 } 118 118 119 - query := "update registrations set registered = strftime('%Y-%m-%dT%H:%M:%SZ', 'now'), read_only = 0" 119 + query := "update registrations set registered = strftime('%Y-%m-%dT%H:%M:%SZ', 'now'), needs_upgrade = 0" 120 120 if len(conditions) > 0 { 121 121 query += " where " + strings.Join(conditions, " and ") 122 122 }
+14 -7
appview/db/spindle.go
··· 10 10 ) 11 11 12 12 type Spindle struct { 13 - Id int 14 - Owner syntax.DID 15 - Instance string 16 - Verified *time.Time 17 - Created time.Time 13 + Id int 14 + Owner syntax.DID 15 + Instance string 16 + Verified *time.Time 17 + Created time.Time 18 + NeedsUpgrade bool 18 19 } 19 20 20 21 type SpindleMember struct { ··· 42 43 } 43 44 44 45 query := fmt.Sprintf( 45 - `select id, owner, instance, verified, created 46 + `select id, owner, instance, verified, created, needs_upgrade 46 47 from spindles 47 48 %s 48 49 order by created ··· 61 62 var spindle Spindle 62 63 var createdAt string 63 64 var verified sql.NullString 65 + var needsUpgrade int 64 66 65 67 if err := rows.Scan( 66 68 &spindle.Id, ··· 68 70 &spindle.Instance, 69 71 &verified, 70 72 &createdAt, 73 + &needsUpgrade, 71 74 ); err != nil { 72 75 return nil, err 73 76 } ··· 86 89 spindle.Verified = &t 87 90 } 88 91 92 + if needsUpgrade != 0 { 93 + spindle.NeedsUpgrade = true 94 + } 95 + 89 96 spindles = append(spindles, spindle) 90 97 } 91 98 ··· 115 122 whereClause = " where " + strings.Join(conditions, " and ") 116 123 } 117 124 118 - query := fmt.Sprintf(`update spindles set verified = strftime('%%Y-%%m-%%dT%%H:%%M:%%SZ', 'now') %s`, whereClause) 125 + query := fmt.Sprintf(`update spindles set verified = strftime('%%Y-%%m-%%dT%%H:%%M:%%SZ', 'now'), needs_upgrade = 0 %s`, whereClause) 119 126 120 127 res, err := e.Exec(query, args...) 121 128 if err != nil {
+5 -57
appview/knots/knots.go
··· 3 3 import ( 4 4 "errors" 5 5 "fmt" 6 - "log" 7 6 "log/slog" 8 7 "net/http" 9 8 "slices" ··· 17 16 "tangled.sh/tangled.sh/core/appview/oauth" 18 17 "tangled.sh/tangled.sh/core/appview/pages" 19 18 "tangled.sh/tangled.sh/core/appview/serververify" 19 + "tangled.sh/tangled.sh/core/appview/xrpcclient" 20 20 "tangled.sh/tangled.sh/core/eventconsumer" 21 21 "tangled.sh/tangled.sh/core/idresolver" 22 22 "tangled.sh/tangled.sh/core/rbac" ··· 49 49 r.With(middleware.AuthMiddleware(k.OAuth)).Post("/{domain}/retry", k.retry) 50 50 r.With(middleware.AuthMiddleware(k.OAuth)).Post("/{domain}/add", k.addMember) 51 51 r.With(middleware.AuthMiddleware(k.OAuth)).Post("/{domain}/remove", k.removeMember) 52 - 53 - r.With(middleware.AuthMiddleware(k.OAuth)).Get("/upgradeBanner", k.banner) 54 52 55 53 return r 56 54 } ··· 399 397 if err != nil { 400 398 l.Error("verification failed", "err", err) 401 399 402 - if errors.Is(err, serververify.FetchError) { 403 - k.Pages.Notice(w, noticeId, "Failed to verify knot, unable to fetch owner.") 400 + if errors.Is(err, xrpcclient.ErrXrpcUnsupported) { 401 + k.Pages.Notice(w, noticeId, "Failed to verify knot, XRPC queries are unsupported on this knot, consider upgrading!") 404 402 return 405 403 } 406 404 ··· 420 418 return 421 419 } 422 420 423 - // if this knot was previously read-only, then emit a record too 421 + // if this knot requires upgrade, then emit a record too 424 422 // 425 423 // this is part of migrating from the old knot system to the new one 426 - if registration.ReadOnly { 424 + if registration.NeedsUpgrade { 427 425 // re-announce by registering under same rkey 428 426 client, err := k.OAuth.AuthorizedClient(r) 429 427 if err != nil { ··· 484 482 return 485 483 } 486 484 updatedRegistration := registrations[0] 487 - 488 - log.Println(updatedRegistration) 489 485 490 486 w.Header().Set("HX-Reswap", "outerHTML") 491 487 k.Pages.KnotListing(w, pages.KnotListingParams{ ··· 678 674 // ok 679 675 k.Pages.HxRefresh(w) 680 676 } 681 - 682 - func (k *Knots) banner(w http.ResponseWriter, r *http.Request) { 683 - user := k.OAuth.GetUser(r) 684 - l := k.Logger.With("handler", "banner") 685 - l = l.With("did", user.Did) 686 - l = l.With("handle", user.Handle) 687 - 688 - allRegistrations, err := db.GetRegistrations( 689 - k.Db, 690 - db.FilterEq("did", user.Did), 691 - ) 692 - if err != nil { 693 - l.Error("non-fatal: failed to get registrations") 694 - return 695 - } 696 - 697 - httpClient := &http.Client{Timeout: 5 * time.Second} 698 - regs404 := []db.Registration{} 699 - for _, reg := range allRegistrations { 700 - healthURL := fmt.Sprintf("http://%s/xrpc/_health", reg.Domain) 701 - 702 - fmt.Println(healthURL) 703 - 704 - req, err := http.NewRequestWithContext(r.Context(), http.MethodGet, healthURL, nil) 705 - if err != nil { 706 - l.Error("failed to create health check request", "domain", reg.Domain, "err", err) 707 - continue 708 - } 709 - 710 - resp, err := httpClient.Do(req) 711 - if err != nil { 712 - l.Error("failed to make health check request", "domain", reg.Domain, "err", err) 713 - continue 714 - } 715 - defer resp.Body.Close() 716 - 717 - if resp.StatusCode == http.StatusNotFound { 718 - regs404 = append(regs404, reg) 719 - } 720 - } 721 - if len(regs404) == 0 { 722 - return 723 - } 724 - 725 - k.Pages.KnotBanner(w, pages.KnotBannerParams{ 726 - Registrations: regs404, 727 - }) 728 - }
+4 -3
appview/pages/pages.go
··· 351 351 return p.execute("user/settings/emails", w, params) 352 352 } 353 353 354 - type KnotBannerParams struct { 354 + type UpgradeBannerParams struct { 355 355 Registrations []db.Registration 356 + Spindles []db.Spindle 356 357 } 357 358 358 - func (p *Pages) KnotBanner(w io.Writer, params KnotBannerParams) error { 359 - return p.executePlain("knots/fragments/bannerRequiresUpgrade", w, params) 359 + func (p *Pages) UpgradeBanner(w io.Writer, params UpgradeBannerParams) error { 360 + return p.executePlain("banner", w, params) 360 361 } 361 362 362 363 type KnotsParams struct {
+23
appview/pages/templates/banner.html
··· 1 + {{ define "banner" }} 2 + <div class="px-6 py-2"> 3 + The following services that you administer will have to be upgraded to be compatible with the latest version of Tangled: 4 + {{ if .Registrations }} 5 + <ul class="list-disc mx-12 my-2"> 6 + {{range .Registrations}} 7 + <li>{{ .Domain }}</li> 8 + {{ end }} 9 + </ul> 10 + Repositories hosted on these knots may not be accessible until upgraded. 11 + {{ end }} 12 + 13 + {{ if .Spindles }} 14 + <ul class="list-disc mx-12 my-2"> 15 + {{range .Spindles}} 16 + <li>{{ .Instance }}</li> 17 + {{ end }} 18 + </ul> 19 + Pipelines may not be executed on these spindles until upgraded. 20 + {{ end }} 21 + <a href="https://tangled.sh/@tangled.sh/core/tree/master/docs/migrations/">Click to read the upgrade guide</a>. 22 + </div> 23 + {{ end }}
-8
appview/pages/templates/knots/fragments/bannerReadOnly.html
··· 1 - {{ define "knots/fragments/bannerReadOnly" }} 2 - <div class="w-full px-6 py-2 -z-15 bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 border border-yellow-200 dark:border-yellow-800 rounded-b drop-shadow-sm"> 3 - A knot ({{range $i, $r := .Registrations}}{{if ne $i 0}}, {{end}}{{ $r.Domain }}{{ end }}) 4 - that you administer is presently read-only. Consider upgrading this knot to 5 - continue creating repositories on it. 6 - <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/migrations/knot-1.7.0.md">Click to read the upgrade guide</a>. 7 - </div> 8 - {{ end }}
-12
appview/pages/templates/knots/fragments/bannerRequiresUpgrade.html
··· 1 - {{ define "knots/fragments/bannerRequiresUpgrade" }} 2 - <div class="px-6 py-2"> 3 - The following knots that you administer will have to be upgraded to be compatible with the latest version of Tangled: 4 - <ul class="list-disc mx-12 my-2"> 5 - {{range $i, $r := .Registrations}} 6 - <li>{{ $r.Domain }}</li> 7 - {{ end }} 8 - </ul> 9 - Repositories hosted on these knots will not be accessible until upgraded. 10 - <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/migrations/knot-1.8.0.md">Click to read the upgrade guide</a>. 11 - </div> 12 - {{ end }}
+2 -2
appview/pages/templates/knots/fragments/knotListing.html
··· 36 36 </span> 37 37 {{ template "knots/fragments/addMemberModal" . }} 38 38 {{ block "knotDeleteButton" . }} {{ end }} 39 - {{ else if .IsReadOnly }} 39 + {{ else if .IsNeedsUpgrade }} 40 40 <span class="bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 {{$style}}"> 41 - {{ i "shield-alert" "w-4 h-4" }} read-only 41 + {{ i "shield-alert" "w-4 h-4" }} needs upgrade 42 42 </span> 43 43 {{ block "knotRetryButton" . }} {{ end }} 44 44 {{ block "knotDeleteButton" . }} {{ end }}
+1 -1
appview/pages/templates/layouts/base.html
··· 53 53 {{ if .LoggedInUser }} 54 54 <div id="upgrade-banner" 55 55 class="z-50 fixed bottom-0 left-0 right-0 w-full flex justify-center bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 border border-yellow-200 dark:border-yellow-800 rounded-b drop-shadow-sm" 56 - hx-get="/knots/upgradeBanner" 56 + hx-get="/banner" 57 57 hx-trigger="load" 58 58 hx-swap="innerHTML"> 59 59 </div>
+11 -27
appview/serververify/verify.go
··· 4 4 "context" 5 5 "errors" 6 6 "fmt" 7 - "io" 8 - "net/http" 9 - "strings" 10 - "time" 11 7 8 + indigoxrpc "github.com/bluesky-social/indigo/xrpc" 9 + "tangled.sh/tangled.sh/core/api/tangled" 12 10 "tangled.sh/tangled.sh/core/appview/db" 11 + "tangled.sh/tangled.sh/core/appview/xrpcclient" 13 12 "tangled.sh/tangled.sh/core/rbac" 14 13 ) 15 14 ··· 24 23 scheme = "http" 25 24 } 26 25 27 - url := fmt.Sprintf("%s://%s/owner", scheme, domain) 28 - req, err := http.NewRequest("GET", url, nil) 29 - if err != nil { 30 - return "", err 31 - } 32 - 33 - client := &http.Client{ 34 - Timeout: 1 * time.Second, 35 - } 36 - 37 - resp, err := client.Do(req.WithContext(ctx)) 38 - if err != nil || resp.StatusCode != 200 { 39 - return "", fmt.Errorf("failed to fetch /owner") 26 + host := fmt.Sprintf("%s://%s", scheme, domain) 27 + xrpcc := &indigoxrpc.Client{ 28 + Host: host, 40 29 } 41 30 42 - body, err := io.ReadAll(io.LimitReader(resp.Body, 1024)) // read atmost 1kb of data 43 - if err != nil { 44 - return "", fmt.Errorf("failed to read /owner response: %w", err) 31 + res, err := tangled.Owner(ctx, xrpcc) 32 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 33 + return "", xrpcerr 45 34 } 46 35 47 - did := strings.TrimSpace(string(body)) 48 - if did == "" { 49 - return "", fmt.Errorf("empty DID in /owner response") 50 - } 51 - 52 - return did, nil 36 + return res.Owner, nil 53 37 } 54 38 55 39 type OwnerMismatch struct { ··· 65 49 func RunVerification(ctx context.Context, domain, expectedOwner string, dev bool) error { 66 50 observedOwner, err := fetchOwner(ctx, domain, dev) 67 51 if err != nil { 68 - return fmt.Errorf("%w: %w", FetchError, err) 52 + return err 69 53 } 70 54 71 55 if observedOwner != expectedOwner {
+4 -3
appview/spindles/spindles.go
··· 16 16 "tangled.sh/tangled.sh/core/appview/oauth" 17 17 "tangled.sh/tangled.sh/core/appview/pages" 18 18 "tangled.sh/tangled.sh/core/appview/serververify" 19 + "tangled.sh/tangled.sh/core/appview/xrpcclient" 19 20 "tangled.sh/tangled.sh/core/idresolver" 20 21 "tangled.sh/tangled.sh/core/rbac" 21 22 "tangled.sh/tangled.sh/core/tid" ··· 404 405 if err != nil { 405 406 l.Error("verification failed", "err", err) 406 407 407 - if errors.Is(err, serververify.FetchError) { 408 - s.Pages.Notice(w, noticeId, "Failed to verify knot, unable to fetch owner.") 408 + if errors.Is(err, xrpcclient.ErrXrpcUnsupported) { 409 + s.Pages.Notice(w, noticeId, "Failed to verify spindle, XRPC queries are unsupported on this spindle, consider upgrading!") 409 410 return 410 411 } 411 412 ··· 442 443 } 443 444 444 445 w.Header().Set("HX-Reswap", "outerHTML") 445 - s.Pages.SpindleListing(w, pages.SpindleListingParams{verifiedSpindle[0]}) 446 + s.Pages.SpindleListing(w, pages.SpindleListingParams{Spindle: verifiedSpindle[0]}) 446 447 } 447 448 448 449 func (s *Spindles) addMember(w http.ResponseWriter, r *http.Request) {
+1
appview/state/router.go
··· 113 113 114 114 r.Get("/", s.HomeOrTimeline) 115 115 r.Get("/timeline", s.Timeline) 116 + r.With(middleware.AuthMiddleware(s.oauth)).Get("/upgradeBanner", s.UpgradeBanner) 116 117 117 118 r.Route("/repo", func(r chi.Router) { 118 119 r.Route("/new", func(r chi.Router) {
+37 -1
appview/state/state.go
··· 228 228 }) 229 229 } 230 230 231 + func (s *State) UpgradeBanner(w http.ResponseWriter, r *http.Request) { 232 + user := s.oauth.GetUser(r) 233 + l := s.logger.With("handler", "UpgradeBanner") 234 + l = l.With("did", user.Did) 235 + l = l.With("handle", user.Handle) 236 + 237 + regs, err := db.GetRegistrations( 238 + s.db, 239 + db.FilterEq("did", user.Did), 240 + db.FilterEq("needs_upgrade", 1), 241 + ) 242 + if err != nil { 243 + l.Error("non-fatal: failed to get registrations") 244 + return 245 + } 246 + 247 + spindles, err := db.GetSpindles( 248 + s.db, 249 + db.FilterEq("did", user.Did), 250 + db.FilterEq("needs_upgrade", 1), 251 + ) 252 + if err != nil { 253 + l.Error("non-fatal: failed to get spindles") 254 + return 255 + } 256 + 257 + if regs == nil && spindles == nil { 258 + return 259 + } 260 + 261 + s.pages.UpgradeBanner(w, pages.UpgradeBannerParams{ 262 + Registrations: regs, 263 + Spindles: spindles, 264 + }) 265 + } 266 + 231 267 func (s *State) Home(w http.ResponseWriter, r *http.Request) { 232 268 timeline, err := db.MakeTimeline(s.db, 5) 233 269 if err != nil { ··· 278 314 279 315 for _, k := range pubKeys { 280 316 key := strings.TrimRight(k.Key, "\n") 281 - w.Write([]byte(fmt.Sprintln(key))) 317 + fmt.Fprintln(w, key) 282 318 } 283 319 } 284 320
-7
knotserver/router.go
··· 72 72 w.Write([]byte("This is a knot server. More info at https://tangled.sh")) 73 73 }) 74 74 75 - owner := func(w http.ResponseWriter, r *http.Request) { 76 - w.Write([]byte(h.c.Server.Owner)) 77 - } 78 - // Deprecated: the sh.tangled.knot.owner xrpc call should be used instead 79 - r.Get("/owner", owner) 80 - 81 75 r.Route("/{did}", func(r chi.Router) { 82 76 r.Route("/{name}", func(r chi.Router) { 83 77 // routes for git operations ··· 90 84 // xrpc apis 91 85 r.Route("/xrpc", func(r chi.Router) { 92 86 r.Get("/_health", h.Version) 93 - r.Get("/sh.tangled.knot.owner", owner) 94 87 r.Mount("/", h.XrpcRouter()) 95 88 }) 96 89
+31
knotserver/xrpc/owner.go
··· 1 + package xrpc 2 + 3 + import ( 4 + "encoding/json" 5 + "net/http" 6 + 7 + "tangled.sh/tangled.sh/core/api/tangled" 8 + xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors" 9 + ) 10 + 11 + func (x *Xrpc) Owner(w http.ResponseWriter, r *http.Request) { 12 + owner := x.Config.Server.Owner 13 + if owner == "" { 14 + writeError(w, xrpcerr.OwnerNotFoundError, http.StatusInternalServerError) 15 + return 16 + } 17 + 18 + response := tangled.Owner_Output{ 19 + Owner: owner, 20 + } 21 + 22 + w.Header().Set("Content-Type", "application/json") 23 + if err := json.NewEncoder(w).Encode(response); err != nil { 24 + x.Logger.Error("failed to encode response", "error", err) 25 + writeError(w, xrpcerr.NewXrpcError( 26 + xrpcerr.WithTag("InternalServerError"), 27 + xrpcerr.WithMessage("failed to encode response"), 28 + ), http.StatusInternalServerError) 29 + return 30 + } 31 + }
+3
knotserver/xrpc/xrpc.go
··· 70 70 // knot query endpoints (no auth required) 71 71 r.Get("/"+tangled.KnotListKeysNSID, x.ListKeys) 72 72 73 + // service query endpoints (no auth required) 74 + r.Get("/"+tangled.OwnerNSID, x.Owner) 75 + 73 76 return r 74 77 } 75 78
-3
spindle/server.go
··· 203 203 w.Write(motd) 204 204 }) 205 205 mux.HandleFunc("/events", s.Events) 206 - mux.HandleFunc("/owner", func(w http.ResponseWriter, r *http.Request) { 207 - w.Write([]byte(s.cfg.Server.Owner)) 208 - }) 209 206 mux.HandleFunc("/logs/{knot}/{rkey}/{name}", s.Logs) 210 207 211 208 mux.Mount("/xrpc", s.XrpcRouter())
+31
spindle/xrpc/owner.go
··· 1 + package xrpc 2 + 3 + import ( 4 + "encoding/json" 5 + "net/http" 6 + 7 + "tangled.sh/tangled.sh/core/api/tangled" 8 + xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors" 9 + ) 10 + 11 + func (x *Xrpc) Owner(w http.ResponseWriter, r *http.Request) { 12 + owner := x.Config.Server.Owner 13 + if owner == "" { 14 + writeError(w, xrpcerr.OwnerNotFoundError, http.StatusInternalServerError) 15 + return 16 + } 17 + 18 + response := tangled.Owner_Output{ 19 + Owner: owner, 20 + } 21 + 22 + w.Header().Set("Content-Type", "application/json") 23 + if err := json.NewEncoder(w).Encode(response); err != nil { 24 + x.Logger.Error("failed to encode response", "error", err) 25 + writeError(w, xrpcerr.NewXrpcError( 26 + xrpcerr.WithTag("InternalServerError"), 27 + xrpcerr.WithMessage("failed to encode response"), 28 + ), http.StatusInternalServerError) 29 + return 30 + } 31 + }
+10 -3
spindle/xrpc/xrpc.go
··· 35 35 func (x *Xrpc) Router() http.Handler { 36 36 r := chi.NewRouter() 37 37 38 - r.With(x.ServiceAuth.VerifyServiceAuth).Post("/"+tangled.RepoAddSecretNSID, x.AddSecret) 39 - r.With(x.ServiceAuth.VerifyServiceAuth).Post("/"+tangled.RepoRemoveSecretNSID, x.RemoveSecret) 40 - r.With(x.ServiceAuth.VerifyServiceAuth).Get("/"+tangled.RepoListSecretsNSID, x.ListSecrets) 38 + r.Group(func(r chi.Router) { 39 + r.Use(x.ServiceAuth.VerifyServiceAuth) 40 + 41 + r.Post("/"+tangled.RepoAddSecretNSID, x.AddSecret) 42 + r.Post("/"+tangled.RepoRemoveSecretNSID, x.RemoveSecret) 43 + r.Get("/"+tangled.RepoListSecretsNSID, x.ListSecrets) 44 + }) 45 + 46 + // service query endpoints (no auth required) 47 + r.Get("/"+tangled.OwnerNSID, x.Owner) 41 48 42 49 return r 43 50 }