oficina / meet Public

Clone
git clone https://amadan.net/oficina/meet

Plain git — no account needed to clone.

Download

Download this file

1//go:build browser
2
3package callstest
4
5import (
6 "bufio"
7 "bytes"
8 "context"
9 "encoding/json"
10 "net/http"
11 "net/http/cookiejar"
12 "net/url"
13 "os/exec"
14 "path/filepath"
15 "testing"
16 "time"
17
18 "amadan.net/oficina/calls/callscore"
19)
20
21func TestNativeBrowserAuthentication(t *testing.T) {
22 // "server" is the apps' Sign in button: the server's own address, no
23 // meeting, landing home.
24 for _, name := range []string{"member", "guest", "server"} {
25 t.Run(name, func(t *testing.T) {
26 rig := newBrowserRig(t)
27 room, token := rig.createMeeting(t)
28 address := memberB
29 target := "/m/" + room
30 want := room
31 switch name {
32 case "guest":
33 rig.ctl.SetAllowlist(memberA)
34 target = "/j/" + token
35 case "server":
36 target = ""
37 want = ""
38 }
39 ctx, cancel := context.WithTimeout(t.Context(), 45*time.Second)
40 defer cancel()
41 auth, err := callscore.BeginAuthentication(ctx, rig.origin+target)
42 if err != nil {
43 t.Fatal(err)
44 }
45 defer auth.Cancel()
46 cmd := exec.CommandContext(ctx, "node", filepath.Join(repoRootForBrowser(t), "test/browser/native-auth.mjs"))
47 stdin, err := cmd.StdinPipe()
48 if err != nil {
49 t.Fatal(err)
50 }
51 stdout, err := cmd.StdoutPipe()
52 if err != nil {
53 t.Fatal(err)
54 }
55 var stderr bytes.Buffer
56 cmd.Stderr = &stderr
57 if err := cmd.Start(); err != nil {
58 t.Fatal(err)
59 }
60 defer stdin.Close()
61 json.NewEncoder(stdin).Encode(map[string]string{"url": auth.BrowserURL(), "address": address, "code": auth.ConfirmationCode()})
62 scanner := bufio.NewScanner(stdout)
63 approved := false
64 for scanner.Scan() {
65 switch scanner.Text() {
66 case "mail":
67 to, link := rig.mail.last()
68 if to != address || link == "" {
69 cancel()
70 cmd.Wait()
71 t.Fatal("missing email")
72 }
73 json.NewEncoder(stdin).Encode(map[string]string{"link": link})
74 case "stage:signin", "stage:email-opened":
75 t.Log(scanner.Text())
76 case "approved":
77 approved = true
78 default:
79 cancel()
80 cmd.Wait()
81 t.Fatal("unexpected browser output")
82 }
83 }
84 if err := cmd.Wait(); err != nil {
85 t.Fatalf("browser: %v: %s", err, stderr.String())
86 }
87 if !approved {
88 t.Fatal("browser did not approve")
89 }
90 result, err := auth.Wait()
91 if err != nil {
92 t.Fatal(err)
93 }
94 if result.Room != want || result.Origin != rig.origin || len(result.Cookies) != 1 {
95 t.Fatal("wrong native destination")
96 }
97 jar, _ := cookiejar.New(nil)
98 origin, _ := url.Parse(rig.origin)
99 c := result.Cookies[0]
100 jar.SetCookies(origin, []*http.Cookie{{Name: c.Name, Value: c.Value}})
101 client := &http.Client{Jar: jar, CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
102 res, err := client.Get(rig.origin + "/m/" + room + "/info")
103 if err != nil {
104 t.Fatal(err)
105 }
106 defer res.Body.Close()
107 if res.StatusCode != 200 {
108 t.Fatalf("native session cannot access meeting: %d", res.StatusCode)
109 }
110 })
111 }
112}
113