-
Notifications
You must be signed in to change notification settings - Fork 0
/
wheel.go
69 lines (63 loc) · 1.78 KB
/
wheel.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
package wheel
import (
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"log"
"math"
"strconv"
"time"
)
//Token token struct
type Token struct {
timeTolerance uint
timeOffset int
vendorEpoch [4]byte
secret []byte
hashToken []byte
}
//NewToken Returns a pointer to a new instance of token struct
func NewToken(secret string) (*Token, error) {
t := new(Token)
t.timeTolerance = 60
_, t.timeOffset = time.Now().Zone()
var err error
t.secret, err = hex.DecodeString(secret)
if err != nil {
log.Printf("Error decoding token secret: %s", err)
}
return t, err
}
//SetTime updates vendorEpoch field with a value based on current time. This assures
//token will not be already expired.
func (t *Token) SetTime(epoch int64) {
vendorEpoch := int64(math.Round((float64(epoch) + float64(t.timeOffset)) / float64(t.timeTolerance)))
t.vendorEpoch = [4]byte{
byte(vendorEpoch),
byte(vendorEpoch >> 8),
byte(vendorEpoch >> 16),
byte(vendorEpoch >> 24),
}
}
//Generate generate/regenerate token value
func (t *Token) Generate() error {
if t.vendorEpoch[0] == 0 && t.vendorEpoch[1] == 0 && t.vendorEpoch[2] == 0 && t.vendorEpoch[3] == 0 {
return errors.New("time not set, UpdateTime() hasn't been called")
}
data := append(t.secret, t.vendorEpoch[:]...)
data = append(data, t.secret...)
h := sha256.New()
h.Write(data)
t.hashToken = h.Sum(nil)
return nil
}
//GetTokenString returns previously generated token
func (t *Token) GetTokenString() string {
hh1 := binary.BigEndian.Uint64(append(make([]byte, 1), t.hashToken[:8]...))
hh2 := binary.BigEndian.Uint64(append(make([]byte, 2), t.hashToken[7:13]...))
bin1 := strconv.Itoa(int(hh1))
bin2 := strconv.Itoa(int(hh2))
return fmt.Sprintf("%s%s", string(bin1)[len(bin1)-4:], string(bin2)[len(bin2)-4:])
}