forked from sfreiberg/gotwilio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
access_token.go
109 lines (92 loc) · 2.39 KB
/
access_token.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
108
109
package gotwilio
import (
"encoding/json"
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
// AccessToken holds everything required to
// create authenticate the client SDKs.
// See https://www.twilio.com/docs/iam/access-tokens
// for further details.
type AccessToken struct {
AccountSid string
APIKeySid string
APIKeySecret string
NotBefore time.Time
ExpiresAt time.Time
Grants []Grant
Identity string
}
// Grant is a perimssion given to the Access Token.
// Types include Chat, Video etc.
type Grant interface {
grantName() string
}
// VideoGrant is the permission to use the Video API
// which can be given to an Access Token.
type VideoGrant struct {
Room string `json:"room,omitempty"`
}
func (g *VideoGrant) grantName() string {
return "video"
}
// NewAccessToken creates a new Access Token which
// can be used to authenticate Twilio Client SDKs
// for a short period of time.
func (twilio *Twilio) NewAccessToken() *AccessToken {
return &AccessToken{
AccountSid: twilio.AccountSid,
APIKeySid: twilio.APIKeySid,
APIKeySecret: twilio.APIKeySecret,
}
}
// AddGrant adds a given Grant to the Access Token.
func (a *AccessToken) AddGrant(grant Grant) *AccessToken {
a.Grants = append(a.Grants, grant)
return a
}
// ToJWT creates a JSON Web Token from the Access Token
// to use in the Client SDKs.
// See https://en.wikipedia.org/wiki/JSON_Web_Token
// for the standard format.
func (a *AccessToken) ToJWT() (string, error) {
claims := &twilioClaims{
jwt.StandardClaims{
Id: a.APIKeySid + fmt.Sprintf("-%d", time.Now().UnixNano()),
Issuer: a.APIKeySid,
Subject: a.AccountSid,
NotBefore: a.NotBefore.Unix(),
ExpiresAt: a.ExpiresAt.Unix(),
},
&grantsClaim{
Identity: a.Identity,
Grants: a.Grants,
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token.Header = map[string]interface{}{
"typ": "JWT",
"alg": "HS256",
"cty": "twilio-fpa;v=1",
}
ss, err := token.SignedString([]byte(a.APIKeySecret))
return ss, err
}
// Private helpers to construct the JWT.
type twilioClaims struct {
jwt.StandardClaims
Grants *grantsClaim `json:"grants"`
}
type grantsClaim struct {
Identity string
Grants []Grant
}
func (g *grantsClaim) MarshalJSON() ([]byte, error) {
data := make(map[string]interface{})
data["identity"] = g.Identity
for _, grant := range g.Grants {
data[grant.grantName()] = grant
}
return json.Marshal(data)
}