github.com/mistwind/reviewdog@v0.0.0-20230322024206-9cfa11856d58/doghouse/server/cookieman/cookieman.go (about) 1 package cookieman 2 3 import ( 4 "encoding/base64" 5 "net/http" 6 ) 7 8 // Cipher is crypt interface to encrypt/decrypt cookie. 9 type Cipher interface { 10 Encrypt(plaintext []byte) ([]byte, error) 11 Decrypt(ciphertext []byte) ([]byte, error) 12 } 13 14 // CookieMan manages cookies. 15 type CookieMan struct { 16 defaultOpt CookieOption 17 cipher Cipher 18 } 19 20 // CookieOption represents cookie options. 21 type CookieOption struct { 22 http.Cookie 23 } 24 25 // CookieStore stores a cookie. 26 type CookieStore struct { 27 name string 28 cookieman *CookieMan 29 opt *CookieOption 30 } 31 32 // Name returns the cookie name this CookieStore manages. 33 func (cs *CookieStore) Name() string { 34 return cs.name 35 } 36 37 // Set sets cookie value. 38 func (cs *CookieStore) Set(w http.ResponseWriter, value []byte) error { 39 return cs.cookieman.Set(w, cs.name, value, cs.opt) 40 } 41 42 // Get returns cookie value. 43 func (cs *CookieStore) Get(r *http.Request) ([]byte, error) { 44 return cs.cookieman.Get(r, cs.name) 45 } 46 47 // Clear clears the cookie. 48 func (cs *CookieStore) Clear(w http.ResponseWriter) { 49 cs.cookieman.Clear(w, cs.name) 50 } 51 52 // New returns new CookieMan with default cookie option. 53 func New(cipher Cipher, defaultOpt CookieOption) *CookieMan { 54 return &CookieMan{defaultOpt: defaultOpt, cipher: cipher} 55 } 56 57 // NewCookieStore returns new CookieStore which manages cookie whose key is 58 // given name and with given cookie option. 59 func (c *CookieMan) NewCookieStore(name string, opt *CookieOption) *CookieStore { 60 return &CookieStore{ 61 name: name, 62 cookieman: c, 63 opt: opt, 64 } 65 } 66 67 // Set sets cookie. 68 func (c *CookieMan) Set(w http.ResponseWriter, name string, value []byte, opt *CookieOption) error { 69 v, err := c.cipher.Encrypt(value) 70 if err != nil { 71 return err 72 } 73 http.SetCookie(w, c.cookie(name, base64.URLEncoding.EncodeToString(v), opt)) 74 return nil 75 } 76 77 // Get returns a cookie with given name. 78 func (c *CookieMan) Get(r *http.Request, name string) ([]byte, error) { 79 cookie, err := r.Cookie(name) 80 if err != nil { 81 return nil, err 82 } 83 ciphertext, err := base64.URLEncoding.DecodeString(cookie.Value) 84 if err != nil { 85 return nil, err 86 } 87 return c.cipher.Decrypt(ciphertext) 88 } 89 90 // Clear clears a cookie with given name. 91 func (c *CookieMan) Clear(w http.ResponseWriter, name string) { 92 opt := &CookieOption{} 93 opt.MaxAge = -1 94 http.SetCookie(w, c.cookie(name, "", opt)) 95 } 96 97 func (c *CookieMan) cookie(name, value string, opt *CookieOption) *http.Cookie { 98 cookie := c.defaultOpt.Cookie 99 cookie.Name = name 100 cookie.Value = value 101 if opt == nil { 102 return &cookie 103 } 104 if opt.Path != "" { 105 cookie.Path = opt.Path 106 } 107 if opt.Domain != "" { 108 cookie.Domain = opt.Domain 109 } 110 if opt.MaxAge != 0 { 111 cookie.MaxAge = opt.MaxAge 112 } 113 if !opt.Expires.IsZero() { 114 cookie.Expires = opt.Expires 115 } 116 if opt.Secure { 117 cookie.Secure = opt.Secure 118 } 119 if opt.HttpOnly { 120 cookie.HttpOnly = opt.HttpOnly 121 } 122 return &cookie 123 }