fork of indigo with slightly nicer lexgen
at main 9.8 kB view raw
1package main 2 3import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 "net/url" 9 "strconv" 10 11 "github.com/bluesky-social/indigo/xrpc" 12 cli "github.com/urfave/cli/v2" 13) 14 15var bgsAdminCmd = &cli.Command{ 16 Name: "bgs", 17 Usage: "sub-commands for administering a BGS", 18 Flags: []cli.Flag{ 19 &cli.StringFlag{ 20 Name: "key", 21 EnvVars: []string{"BGS_ADMIN_KEY"}, 22 }, 23 &cli.StringFlag{ 24 Name: "bgs", 25 Value: "http://localhost:2470", 26 }, 27 }, 28 Subcommands: []*cli.Command{ 29 bgsListUpstreamsCmd, 30 bgsKickConnectionCmd, 31 bgsListDomainBansCmd, 32 bgsBanDomainCmd, 33 bgsTakedownRepoCmd, 34 bgsSetNewSubsEnabledCmd, 35 bgsCompactRepo, 36 bgsCompactAll, 37 bgsResetRepo, 38 }, 39} 40 41var bgsListUpstreamsCmd = &cli.Command{ 42 Name: "list", 43 Action: func(cctx *cli.Context) error { 44 url := cctx.String("bgs") + "/admin/subs/getUpstreamConns" 45 req, err := http.NewRequest("GET", url, nil) 46 if err != nil { 47 return err 48 } 49 50 auth := cctx.String("key") 51 req.Header.Set("Authorization", "Bearer "+auth) 52 53 resp, err := http.DefaultClient.Do(req) 54 if err != nil { 55 return err 56 } 57 58 if resp.StatusCode != 200 { 59 var e xrpc.XRPCError 60 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 61 return err 62 } 63 64 return &e 65 } 66 67 var out []string 68 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 69 return err 70 } 71 72 for _, h := range out { 73 fmt.Println(h) 74 } 75 76 return nil 77 }, 78} 79 80var bgsKickConnectionCmd = &cli.Command{ 81 Name: "kick", 82 Usage: "tell Relay/BGS to drop the subscription connection", 83 ArgsUsage: "<host>", 84 Flags: []cli.Flag{ 85 &cli.BoolFlag{ 86 Name: "ban", 87 Usage: "make the disconnect sticky", 88 }, 89 }, 90 Action: func(cctx *cli.Context) error { 91 uu := cctx.String("bgs") + "/admin/subs/killUpstream?host=" 92 93 uu += url.QueryEscape(cctx.Args().First()) 94 95 if cctx.Bool("ban") { 96 uu += "&block=true" 97 } 98 99 req, err := http.NewRequest("POST", uu, nil) 100 if err != nil { 101 return err 102 } 103 104 auth := cctx.String("key") 105 req.Header.Set("Authorization", "Bearer "+auth) 106 107 resp, err := http.DefaultClient.Do(req) 108 if err != nil { 109 return err 110 } 111 112 if resp.StatusCode != 200 { 113 var e xrpc.XRPCError 114 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 115 return err 116 } 117 118 return &e 119 } 120 121 var out map[string]any 122 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 123 return err 124 } 125 126 fmt.Println(out) 127 128 return nil 129 }, 130} 131 132var bgsListDomainBansCmd = &cli.Command{ 133 Name: "list-domain-bans", 134 Action: func(cctx *cli.Context) error { 135 url := cctx.String("bgs") + "/admin/subs/listDomainBans" 136 req, err := http.NewRequest("GET", url, nil) 137 if err != nil { 138 return err 139 } 140 141 auth := cctx.String("key") 142 req.Header.Set("Authorization", "Bearer "+auth) 143 144 resp, err := http.DefaultClient.Do(req) 145 if err != nil { 146 return err 147 } 148 149 if resp.StatusCode != 200 { 150 var e xrpc.XRPCError 151 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 152 return err 153 } 154 155 return &e 156 } 157 158 var out []string 159 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 160 return err 161 } 162 163 for _, h := range out { 164 fmt.Println(h) 165 } 166 167 return nil 168 }, 169} 170 171var bgsBanDomainCmd = &cli.Command{ 172 Name: "ban-domain", 173 ArgsUsage: "<domain>", 174 Action: func(cctx *cli.Context) error { 175 url := cctx.String("bgs") + "/admin/subs/banDomain" 176 177 b, err := json.Marshal(map[string]string{ 178 "domain": cctx.Args().First(), 179 }) 180 if err != nil { 181 return err 182 } 183 184 req, err := http.NewRequest("POST", url, bytes.NewReader(b)) 185 if err != nil { 186 return err 187 } 188 189 req.Header.Set("Content-Type", "application/json") 190 191 auth := cctx.String("key") 192 req.Header.Set("Authorization", "Bearer "+auth) 193 194 resp, err := http.DefaultClient.Do(req) 195 if err != nil { 196 return err 197 } 198 199 if resp.StatusCode != 200 { 200 var e xrpc.XRPCError 201 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 202 return err 203 } 204 205 return &e 206 } 207 208 var out map[string]any 209 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 210 return err 211 } 212 213 fmt.Println(out) 214 215 return nil 216 }, 217} 218 219var bgsTakedownRepoCmd = &cli.Command{ 220 Name: "take-down-repo", 221 ArgsUsage: "<did>", 222 Action: func(cctx *cli.Context) error { 223 url := cctx.String("bgs") + "/admin/repo/takeDown" 224 225 b, err := json.Marshal(map[string]string{ 226 "did": cctx.Args().First(), 227 }) 228 if err != nil { 229 return err 230 } 231 232 req, err := http.NewRequest("POST", url, bytes.NewReader(b)) 233 if err != nil { 234 return err 235 } 236 237 req.Header.Set("Content-Type", "application/json") 238 239 auth := cctx.String("key") 240 req.Header.Set("Authorization", "Bearer "+auth) 241 242 resp, err := http.DefaultClient.Do(req) 243 if err != nil { 244 return err 245 } 246 247 if resp.StatusCode != 200 { 248 var e xrpc.XRPCError 249 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 250 return err 251 } 252 253 return &e 254 } 255 256 var out map[string]any 257 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 258 return err 259 } 260 261 fmt.Println(out) 262 263 return nil 264 }, 265} 266 267var bgsSetNewSubsEnabledCmd = &cli.Command{ 268 Name: "set-accept-subs", 269 ArgsUsage: "<boolean>", 270 Usage: "set configuration for whether new subscriptions are allowed", 271 Action: func(cctx *cli.Context) error { 272 url := cctx.String("bgs") + "/admin/subs/setEnabled" 273 274 bv, err := strconv.ParseBool(cctx.Args().First()) 275 if err != nil { 276 return err 277 } 278 279 url += fmt.Sprintf("?enabled=%v", bv) 280 281 req, err := http.NewRequest("POST", url, nil) 282 if err != nil { 283 return err 284 } 285 286 auth := cctx.String("key") 287 req.Header.Set("Authorization", "Bearer "+auth) 288 289 resp, err := http.DefaultClient.Do(req) 290 if err != nil { 291 return err 292 } 293 294 if resp.StatusCode != 200 { 295 var e xrpc.XRPCError 296 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 297 return err 298 } 299 300 return &e 301 } 302 303 var out map[string]any 304 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 305 return err 306 } 307 308 fmt.Println(out) 309 310 return nil 311 }, 312} 313 314var bgsCompactRepo = &cli.Command{ 315 Name: "compact-repo", 316 ArgsUsage: "<did>", 317 Flags: []cli.Flag{ 318 &cli.BoolFlag{ 319 Name: "fast", 320 }, 321 }, 322 Action: func(cctx *cli.Context) error { 323 uu, err := url.Parse(cctx.String("bgs") + "/admin/repo/compact") 324 if err != nil { 325 return err 326 } 327 328 q := uu.Query() 329 did := cctx.Args().First() 330 q.Add("did", did) 331 332 if cctx.Bool("fast") { 333 q.Add("fast", "true") 334 } 335 336 uu.RawQuery = q.Encode() 337 338 req, err := http.NewRequest("POST", uu.String(), nil) 339 if err != nil { 340 return err 341 } 342 343 auth := cctx.String("key") 344 req.Header.Set("Authorization", "Bearer "+auth) 345 346 resp, err := http.DefaultClient.Do(req) 347 if err != nil { 348 return err 349 } 350 351 if resp.StatusCode != 200 { 352 var e xrpc.XRPCError 353 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 354 return err 355 } 356 357 return &e 358 } 359 360 var out map[string]any 361 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 362 return err 363 } 364 365 fmt.Println(out) 366 367 return nil 368 }, 369} 370 371var bgsCompactAll = &cli.Command{ 372 Name: "compact-all", 373 Flags: []cli.Flag{ 374 &cli.BoolFlag{ 375 Name: "dry", 376 }, 377 &cli.IntFlag{ 378 Name: "limit", 379 }, 380 &cli.IntFlag{ 381 Name: "threshold", 382 }, 383 &cli.BoolFlag{ 384 Name: "fast", 385 }, 386 }, 387 Action: func(cctx *cli.Context) error { 388 uu, err := url.Parse(cctx.String("bgs") + "/admin/repo/compactAll") 389 if err != nil { 390 return err 391 } 392 393 q := uu.Query() 394 if cctx.Bool("dry") { 395 q.Add("dry", "true") 396 } 397 398 if cctx.Bool("fast") { 399 q.Add("fast", "true") 400 } 401 402 if cctx.IsSet("limit") { 403 q.Add("limit", fmt.Sprint(cctx.Int("limit"))) 404 } 405 406 if cctx.IsSet("threshold") { 407 q.Add("threshold", fmt.Sprint(cctx.Int("threshold"))) 408 } 409 410 uu.RawQuery = q.Encode() 411 412 req, err := http.NewRequest("POST", uu.String(), nil) 413 if err != nil { 414 return err 415 } 416 417 auth := cctx.String("key") 418 req.Header.Set("Authorization", "Bearer "+auth) 419 420 resp, err := http.DefaultClient.Do(req) 421 if err != nil { 422 return err 423 } 424 425 if resp.StatusCode != 200 { 426 var e xrpc.XRPCError 427 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 428 return err 429 } 430 431 return &e 432 } 433 434 var out map[string]any 435 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 436 return err 437 } 438 439 fmt.Println(out) 440 441 return nil 442 }, 443} 444 445var bgsResetRepo = &cli.Command{ 446 Name: "reset-repo", 447 ArgsUsage: "<did>", 448 Action: func(cctx *cli.Context) error { 449 url := cctx.String("bgs") + "/admin/repo/reset" 450 451 did := cctx.Args().First() 452 url += fmt.Sprintf("?did=%s", did) 453 454 req, err := http.NewRequest("POST", url, nil) 455 if err != nil { 456 return err 457 } 458 459 auth := cctx.String("key") 460 req.Header.Set("Authorization", "Bearer "+auth) 461 462 resp, err := http.DefaultClient.Do(req) 463 if err != nil { 464 return err 465 } 466 467 if resp.StatusCode != 200 { 468 var e xrpc.XRPCError 469 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 470 return err 471 } 472 473 return &e 474 } 475 476 var out map[string]any 477 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 478 return err 479 } 480 481 fmt.Println(out) 482 483 return nil 484 }, 485} 486 487var bgsSetTrustedDomains = &cli.Command{ 488 Name: "set-trusted-domain", 489 Action: func(cctx *cli.Context) error { 490 url := cctx.String("bgs") + "/admin/pds/addTrustedDomain" 491 492 domain := cctx.Args().First() 493 url += fmt.Sprintf("?domain=%s", domain) 494 495 req, err := http.NewRequest("POST", url, nil) 496 if err != nil { 497 return err 498 } 499 500 auth := cctx.String("key") 501 req.Header.Set("Authorization", "Bearer "+auth) 502 503 resp, err := http.DefaultClient.Do(req) 504 if err != nil { 505 return err 506 } 507 508 if resp.StatusCode != 200 { 509 var e xrpc.XRPCError 510 if err := json.NewDecoder(resp.Body).Decode(&e); err != nil { 511 return err 512 } 513 514 return &e 515 } 516 517 var out map[string]any 518 if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { 519 return err 520 } 521 522 fmt.Println(out) 523 524 return nil 525 }, 526}