feat(11.1-04): add the Backend section, the remaining Services pages and the concept map links
- docs/backend: admin controllers, forms, lists and filters, relation manager, users and permissions, settings, partials and widgets, admin SPA - docs/services: storage, outbound HTTP, realtime, Web Push, search, parity testing and the Frontend and AJAX (not provided) page - Examples for cabana (with testdata/docs YAML), fetchguard, lighthouse and its centrifugo driver, flare, beachcomber and typesense, tide; lighthouse and beachcomber TestDocs* regions run on their Postgres harnesses - concept map rows link their guide pages and the not-provided rows the Frontend and AJAX page; index lists Backend, Database and Services - TestDocsRequiredPages asserts the D-08 section order
This commit is contained in:
102
modules/lighthouse/centrifugo/example_test.go
Normal file
102
modules/lighthouse/centrifugo/example_test.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package centrifugo_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/compass"
|
||||
"git.golem15.com/golem15/summercms/modules/lighthouse"
|
||||
"git.golem15.com/golem15/summercms/modules/lighthouse/centrifugo"
|
||||
"git.golem15.com/golem15/summercms/modules/surf"
|
||||
)
|
||||
|
||||
// newApp returns an app whose config selects a realtime driver.
|
||||
func newApp(settings map[string]any) (*backpack.App, error) {
|
||||
cfg, err := compass.Open(compass.Options{Dir: "config", Env: "development", Environ: []string{}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range settings {
|
||||
if err := cfg.Set(k, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return backpack.New(cfg), nil
|
||||
}
|
||||
|
||||
func ExampleProxyHandler() {
|
||||
svc, err := lighthouse.From(backpack.New(nil))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// Members of blog 7 may subscribe to its channels.
|
||||
err = svc.Registry().Register("blog", lighthouse.AuthorizerFunc(
|
||||
func(ctx context.Context, userID uint, channel string) lighthouse.Result {
|
||||
if userID == 42 && lighthouse.ChannelID(channel) == 7 {
|
||||
return lighthouse.Allowed(nil)
|
||||
}
|
||||
return lighthouse.Denied("not a member of the blog")
|
||||
}))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// realtime.centrifugo.proxy_secret; set it through the environment.
|
||||
proxy := centrifugo.ProxyHandler(svc, centrifugo.Config{ProxySecret: "test-only-proxy-secret"})
|
||||
|
||||
// What Centrifugo posts to the subscribe proxy.
|
||||
subscribe := func(secret, user, channel string) {
|
||||
body := fmt.Sprintf(`{"client":"c1","user":%q,"channel":%q}`, user, channel)
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/realtime/subscribe", strings.NewReader(body))
|
||||
req.Header.Set("X-Centrifugo-Secret", secret)
|
||||
rec := httptest.NewRecorder()
|
||||
proxy.ServeHTTP(rec, req)
|
||||
fmt.Println(rec.Code, strings.TrimSpace(rec.Body.String()))
|
||||
}
|
||||
subscribe("test-only-proxy-secret", "42", "blog:7")
|
||||
subscribe("test-only-proxy-secret", "5", "blog:7")
|
||||
subscribe("wrong-secret", "42", "blog:7")
|
||||
// Output:
|
||||
// 200 {"result":{"info":[]}}
|
||||
// 200 {"error":{"code":403,"message":"Access denied"}}
|
||||
// 200 {"error":{"code":403,"message":"Access denied"}}
|
||||
}
|
||||
|
||||
func ExampleDriver_Routes() {
|
||||
app, err := newApp(map[string]any{"realtime.driver": "centrifugo"})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
svc, err := lighthouse.From(app)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
// In a plugin's Routes method, r is the router the plugin receives.
|
||||
r := surf.New(nil)
|
||||
err = lighthouse.Mount(r, svc.Driver(), lighthouse.Surfaces{
|
||||
UserAuth: surf.Use("acme.auth"),
|
||||
Middleware: surf.Use("throttle:60,1"),
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
for _, rt := range r.Routes() {
|
||||
fmt.Println(rt.Method, rt.Pattern, rt.Middleware, "raw:", rt.Raw)
|
||||
}
|
||||
|
||||
// A user route without a guard is refused.
|
||||
err = lighthouse.Mount(surf.New(nil), svc.Driver(), lighthouse.Surfaces{})
|
||||
fmt.Println(err != nil)
|
||||
// Output:
|
||||
// GET /api/realtime/token [acme.auth throttle:60,1] raw: false
|
||||
// POST /api/realtime/subscribe [throttle:60,1] raw: true
|
||||
// true
|
||||
}
|
||||
Reference in New Issue
Block a user