Initial commit
This commit is contained in:
124
cpone-dashboard/menu/auth/session.go
Normal file
124
cpone-dashboard/menu/auth/session.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const cookieName = "cpone_session"
|
||||
const projectCookieName = "cpone_project_mcu_id"
|
||||
|
||||
type ctxKey string
|
||||
|
||||
const userCtxKey ctxKey = "username"
|
||||
|
||||
// Username returns the logged-in username from the request context.
|
||||
func Username(r *http.Request) string {
|
||||
v, _ := r.Context().Value(userCtxKey).(string)
|
||||
return v
|
||||
}
|
||||
|
||||
func setContext(r *http.Request, username string) *http.Request {
|
||||
return r.WithContext(context.WithValue(r.Context(), userCtxKey, username))
|
||||
}
|
||||
|
||||
func SetSession(w http.ResponseWriter, username, secret string) {
|
||||
val := encode(username) + "." + sign(username, secret)
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: cookieName,
|
||||
Value: val,
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
Expires: time.Now().Add(24 * time.Hour),
|
||||
})
|
||||
}
|
||||
|
||||
func ClearSession(w http.ResponseWriter) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: cookieName,
|
||||
Value: "",
|
||||
Path: "/",
|
||||
MaxAge: -1,
|
||||
})
|
||||
}
|
||||
|
||||
func SetSelectedProject(w http.ResponseWriter, mcuID int) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: projectCookieName,
|
||||
Value: strconv.Itoa(mcuID),
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
Expires: time.Now().Add(7 * 24 * time.Hour),
|
||||
})
|
||||
}
|
||||
|
||||
func ClearSelectedProject(w http.ResponseWriter) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: projectCookieName,
|
||||
Value: "",
|
||||
Path: "/",
|
||||
MaxAge: -1,
|
||||
})
|
||||
}
|
||||
|
||||
func SelectedProjectID(r *http.Request) int {
|
||||
c, err := r.Cookie(projectCookieName)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
id, err := strconv.Atoi(strings.TrimSpace(c.Value))
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func getSession(r *http.Request, secret string) string {
|
||||
c, err := r.Cookie(cookieName)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
parts := strings.SplitN(c.Value, ".", 2)
|
||||
if len(parts) != 2 {
|
||||
return ""
|
||||
}
|
||||
username, err := decode(parts[0])
|
||||
if err != nil || username == "" {
|
||||
return ""
|
||||
}
|
||||
if !hmac.Equal([]byte(sign(username, secret)), []byte(parts[1])) {
|
||||
return ""
|
||||
}
|
||||
return username
|
||||
}
|
||||
|
||||
func newUUID() string {
|
||||
b := make([]byte, 16)
|
||||
rand.Read(b)
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
func sign(username, secret string) string {
|
||||
mac := hmac.New(sha256.New, []byte(secret))
|
||||
mac.Write([]byte(username))
|
||||
return base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
|
||||
}
|
||||
|
||||
func encode(s string) string {
|
||||
return base64.RawURLEncoding.EncodeToString([]byte(s))
|
||||
}
|
||||
|
||||
func decode(s string) (string, error) {
|
||||
b, err := base64.RawURLEncoding.DecodeString(s)
|
||||
return string(b), err
|
||||
}
|
||||
Reference in New Issue
Block a user