-
Notifications
You must be signed in to change notification settings - Fork 0
/
token.go
67 lines (59 loc) · 1.47 KB
/
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
package auth
import (
"crypto/rand"
"fmt"
"io"
"math/big"
"sync"
"time"
"github.com/google/uuid"
)
var tokenPool *sync.Pool
func init() {
tokenPool = &sync.Pool{
New: func() interface{} {
return &Token{}
},
}
buf := make([]byte, 1)
_, err := io.ReadFull(rand.Reader, buf)
if err != nil {
panic(fmt.Sprintf("crypto/rand is unavailable: Read() failed with %v", err))
}
}
func newToken() *Token {
return tokenPool.New().(*Token)
}
func releaseToken(t *Token) {
*t = Token{}
userPool.Put(t)
}
type Token struct {
ID string `storm:"id" json:"id"`
Token string `json:"-"`
Description string `json:"description"`
Owner string `storm:"index" json:"owner"`
Created time.Time `json:"created"`
ExpiresAt time.Time `json:"expires_at"`
Scope Scope `json:"scope"`
}
func generateToken(owner, description string, scope Scope, expires time.Time, size int) (Token, error) {
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
ret := make([]byte, size)
for i := 0; i < size; i++ {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
if err != nil {
return Token{}, fmt.Errorf("could not generate token: %w", err)
}
ret[i] = letters[num.Int64()]
}
return Token{
ID: uuid.New().String(),
Token: string(ret),
Description: description,
Owner: owner,
Created: time.Now().In(time.UTC),
Scope: scope,
ExpiresAt: expires,
}, nil
}