~ghost08/graphiql

ref: b8c3ae90bfca91f8513a4dcea013193f629d5a01 graphiql/graphiql.go -rw-r--r-- 2.0 KiB
b8c3ae90Vladimír Magyar Add LICENSE 1 year, 25 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package graphiql

import (
	"context"
	"fmt"
	"net/http"
	"strings"
)

var page = `
<html>
  <head>
    <title>GraphiQL</title>
    <link href="https://unpkg.com/graphiql/graphiql.min.css" rel="stylesheet" />
  </head>
  <body style="margin: 0;">
    <div id="graphiql" style="height: 100vh;"></div>
    <script crossorigin src="https://unpkg.com/react/umd/react.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
    <script crossorigin src="https://unpkg.com/graphiql/graphiql.min.js"></script>
    <script>
      const graphQLFetcher = graphQLParams =>
        fetch('/api', {
          method: 'post',
          headers: { $headers 'Content-Type': 'application/json' },
          body: JSON.stringify(graphQLParams),
		  theme: 'dark',
        })
          .then(response => response.json())
          .catch(() => response.text());
      ReactDOM.render(
        React.createElement(GraphiQL, { fetcher: graphQLFetcher }),
        document.getElementById('graphiql'),
      );
    </script>
  </body>
</html>
`

type Login func(ctx context.Context, username, password string) (http.Header, error)

func Handler(login Login) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		user, pass, ok := r.BasicAuth()
		if !ok && login != nil {
			w.Header().Set("WWW-Authenticate", `Basic realm="Please enter your username and password"`)
			w.WriteHeader(401)
			w.Write([]byte("Unauthorised.\n"))
			return
		}
		var headerString strings.Builder
		if login != nil {
			header, err := login(r.Context(), user, pass)
			if err != nil {
				w.Header().Set("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, err))
				w.WriteHeader(401)
				w.Write([]byte("Unauthorized.\n"))
				return
			}
			for key, values := range header {
				for _, value := range values {
					headerString.WriteString(fmt.Sprintf(`"%s":"%s",`, key, value))
				}
			}
		}
		w.Write([]byte(strings.ReplaceAll(page, "$headers", headerString.String())))
	})
}