-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathauthn_webhook.go
107 lines (91 loc) · 3.2 KB
/
authn_webhook.go
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package ayame
import (
"encoding/json"
"fmt"
"io"
"net/url"
"time"
)
type authnWebhookRequest struct {
RoomID string `json:"roomId"`
ClientID string `json:"clientId"`
ConnectionID string `json:"connectionId"`
SignalingKey *string `json:"signalingKey,omitempty"`
AuthnMetadata *interface{} `json:"authnMetadata,omitempty"`
AyameClient *string `json:"ayameClient,omitempty"`
Libwebrtc *string `json:"libwebrtc,omitempty"`
Environment *string `json:"environment,omitempty"`
}
type authnWebhookResponse struct {
Allowed *bool `json:"allowed"`
IceServers *[]iceServer `json:"iceServers"`
Reason *string `json:"reason"`
AuthzMetadata *interface{} `json:"authzMetadata"`
}
func (c *connection) authnWebhook() (*authnWebhookResponse, error) {
if c.config.AuthnWebhookURL == "" {
var allowed = true
authnWebhookResponse := &authnWebhookResponse{Allowed: &allowed}
return authnWebhookResponse, nil
}
req := &authnWebhookRequest{
RoomID: c.roomID,
ClientID: c.clientID,
ConnectionID: c.ID,
SignalingKey: c.signalingKey,
AuthnMetadata: c.authnMetadata,
AyameClient: c.ayameClient,
Libwebrtc: c.libwebrtc,
Environment: c.environment,
}
start := time.Now()
resp, err := c.postRequest(c.config.AuthnWebhookURL, req)
if err != nil {
c.errLog().Err(err).Caller().Msg("AuthnWebhookError")
return nil, errAuthnWebhook
}
// http://ikawaha.hateblo.jp/entry/2015/06/07/074155
defer resp.Body.Close()
c.webhookLog("authnReq", req)
u, err := url.Parse(c.config.AuthnWebhookURL)
if err != nil {
c.errLog().Err(err).Caller().Msg("AuthnWebhookError")
return nil, errAuthnWebhook
}
statusCode := fmt.Sprintf("%d", resp.StatusCode)
m := c.metrics
m.IncWebhookReqCnt(statusCode, "POST", u.Host, u.Path)
m.ObserveWebhookReqDur(statusCode, "POST", u.Host, u.Path, time.Since(start).Seconds())
// TODO: ヘッダーのサイズも計測する
m.ObserveWebhookReqSz(statusCode, "POST", u.Host, u.Path, resp.Request.ContentLength)
m.ObserveWebhookResSz(statusCode, "POST", u.Host, u.Path, resp.ContentLength)
body, err := io.ReadAll(resp.Body)
if err != nil {
c.errLog().Bytes("body", body).Err(err).Caller().Msg("AuthnWebhookResponseError")
return nil, err
}
// ログ出力用
httpResponse := &httpResponse{
Status: resp.Status,
Proto: resp.Proto,
Header: resp.Header,
Body: string(body),
}
// 200 以外で返ってきたときはエラーとする
if resp.StatusCode != 200 {
c.errLog().Interface("resp", httpResponse).Caller().Msg("AuthnWebhookUnexpectedStatusCode")
return nil, errAuthnWebhookUnexpectedStatusCode
}
c.webhookLog("authnResp", httpResponse)
authnWebhookResponse := authnWebhookResponse{}
if err := json.Unmarshal(body, &authnWebhookResponse); err != nil {
c.errLog().Err(err).Caller().Msg("AuthnWebhookResponseError")
return nil, errAuthnWebhookResponse
}
if authnWebhookResponse.Reason == nil {
m.IncAuthnWebhookCnt(statusCode, "POST", u.Host, u.Path, *authnWebhookResponse.Allowed, "")
} else {
m.IncAuthnWebhookCnt(statusCode, "POST", u.Host, u.Path, *authnWebhookResponse.Allowed, *authnWebhookResponse.Reason)
}
return &authnWebhookResponse, nil
}