-
Notifications
You must be signed in to change notification settings - Fork 4
/
tokeniser.go
140 lines (125 loc) · 3.82 KB
/
tokeniser.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package auth
import (
"crypto/rand"
"crypto/rsa"
"os"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/pborman/uuid"
)
const (
// TokenValidPeriod is the default amount of minutes a token is valid
TokenValidPeriod = 60
)
// Tokeniser is the auth tokeniser for JSON Web Tokens
type Tokeniser struct {
privateKey *rsa.PrivateKey
publicKey *rsa.PublicKey
authIssuer string
}
// NewMockTokeniser creates a new tokeniser with a random key pair
func NewMockTokeniser() (*Tokeniser, error) {
reader := rand.Reader
bitSize := 2048
privateKey, err := rsa.GenerateKey(reader, bitSize)
if err != nil {
return nil, err
}
publicKey := &privateKey.PublicKey
issuer, err := os.Hostname()
if err != nil {
return nil, err
}
return NewTokeniser(privateKey, publicKey, issuer), nil
}
// NewTokeniserFromPublicKey parses a public key to
func NewTokeniserFromPublicKey(pkb []byte) (*Tokeniser, error) {
publicKey, err := jwt.ParseRSAPublicKeyFromPEM(pkb)
if err != nil {
return nil, err
}
return &Tokeniser{publicKey: publicKey}, nil
}
// NewTokeniserFromKeyPair parses a public key to
func NewTokeniserFromKeyPair(privateKeyB, publicKeyB []byte, issuer string) (*Tokeniser, error) {
privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyB)
if err != nil {
return nil, err
}
publicKey, err := jwt.ParseRSAPublicKeyFromPEM(publicKeyB)
if err != nil {
return nil, err
}
return NewTokeniser(privateKey, publicKey, issuer), nil
}
// NewTokeniser returns a new JWT instance
func NewTokeniser(privateKey *rsa.PrivateKey, publicKey *rsa.PublicKey, issuer string) *Tokeniser {
return &Tokeniser{
privateKey: privateKey,
publicKey: publicKey,
authIssuer: issuer,
}
}
// GenerateToken generates and returns an authentication token.
func (t *Tokeniser) GenerateToken(consumer *Consumer) (string, error) {
// Create our claims
// NOTE: The consumer is sanitised
claims := Claims{
Consumer: *consumer,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(time.Duration(TokenValidPeriod) * time.Minute).Unix(),
Issuer: t.authIssuer,
Id: uuid.New(),
},
}
// Create the token
newToken := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
// Sign the token
return newToken.SignedString(t.privateKey)
}
// ValidateToken validates an authentication token and returns true/false
// based upon the result.
func (t *Tokeniser) ValidateToken(raw string) (bool, error) {
token, err := jwt.ParseWithClaims(raw, &Claims{}, checkSignatureFunc(t.publicKey))
// Bail out if the token could not be parsed
if err != nil {
return false, handleParseErr(err)
}
// Check the claims and token are valid.
if _, ok := token.Claims.(*Claims); !ok || !token.Valid {
return false, ErrTokenInvalid
}
return true, nil
}
// ParseToken takes a string and returns a valid jwt token
func (t *Tokeniser) ParseToken(raw string) (*jwt.Token, error) {
// Parse the JWT token
token, err := jwt.ParseWithClaims(raw, &Claims{}, checkSignatureFunc(t.publicKey))
// Bail out if the token could not be parsed
if err != nil {
return nil, handleParseErr(err)
}
// Check the claims and token are valid
if _, ok := token.Claims.(*Claims); !ok || !token.Valid {
return nil, ErrTokenInvalid
}
return token, nil
}
// GetTokenConsumer returns the consumer details for a given auth token.
func (t *Tokeniser) GetTokenConsumer(raw string) *Consumer {
token, _ := jwt.ParseWithClaims(raw, &Claims{}, checkSignatureFunc(t.publicKey))
claims, ok := token.Claims.(*Claims)
if !ok {
return nil
}
return &claims.Consumer
}
// GetTokenExpiry returns the expiry date for a given auth token.
func (t *Tokeniser) GetTokenExpiry(raw string) time.Time {
var expiry time.Time
token, _ := jwt.ParseWithClaims(raw, &Claims{}, checkSignatureFunc(t.publicKey))
if claims, ok := token.Claims.(*Claims); ok {
expiry = time.Unix(claims.ExpiresAt, 0)
}
return expiry
}