gauth/gauth.go (view raw)
1package gauth
2
3import (
4 "crypto/rand"
5 "encoding/hex"
6 "net/http"
7 "time"
8
9 "golang.org/x/crypto/bcrypt"
10)
11
12type Gauth struct {
13 Pepper string
14 SessionTokenDuration time.Duration
15 LongSessionTokenDuration time.Duration
16}
17
18func NewGauth(pepper string, sessionTokenDuration, longSessionTokenDuration time.Duration) *Gauth {
19 return &Gauth{
20 Pepper: pepper,
21 SessionTokenDuration: sessionTokenDuration,
22 LongSessionTokenDuration: longSessionTokenDuration,
23 }
24}
25
26func (g Gauth) HashPassword(password string) (string, error) {
27 hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password+g.Pepper), bcrypt.DefaultCost)
28 if err != nil {
29 return "", err
30 }
31 return string(hashedPassword), nil
32}
33
34func (g Gauth) CheckPassword(password, hash string) bool {
35 err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password+g.Pepper))
36 return err == nil
37}
38
39func (g Gauth) GenerateRandomToken() (string, error) {
40 token := make([]byte, 32)
41 _, err := rand.Read(token)
42 if err != nil {
43 return "", err
44 }
45 return hex.EncodeToString(token), nil
46}
47
48func (g Gauth) GenerateCookie(long bool) (*http.Cookie, error) {
49 sessionToken, err := g.GenerateRandomToken()
50 if err != nil {
51 return nil, err
52 }
53
54 var expiration time.Duration
55 if long {
56 expiration = g.LongSessionTokenDuration
57 } else {
58 expiration = g.SessionTokenDuration
59 }
60
61 return &http.Cookie{
62 Name: "session_token",
63 Value: sessionToken,
64 Expires: time.Now().Add(expiration),
65 Path: "/",
66 HttpOnly: true,
67 Secure: true,
68 }, nil
69}
70
71func (g Gauth) GenerateEmptyCookie() *http.Cookie {
72 return &http.Cookie{
73 Name: "session_token",
74 Value: "",
75 Expires: time.Now().Add(-1 * time.Hour),
76 Path: "/",
77 }
78}