package auth import ( "net/http" "github.com/gorilla/sessions" "golang.org/x/crypto/bcrypt" ) const SessionName = "vpn_panel_session" type Manager struct { store *sessions.CookieStore } func New(secret string) *Manager { store := sessions.NewCookieStore([]byte(secret)) store.Options = &sessions.Options{ Path: "/", MaxAge: 86400 * 7, HttpOnly: true, SameSite: http.SameSiteLaxMode, } return &Manager{store: store} } func CheckPassword(hash, password string) bool { return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil } func (m *Manager) Login(w http.ResponseWriter, r *http.Request, userID, email, name string) error { sess, err := m.store.Get(r, SessionName) if err != nil { sess, _ = m.store.New(r, SessionName) } sess.Values["authenticated"] = true sess.Values["user_id"] = userID sess.Values["email"] = email sess.Values["name"] = name return sess.Save(r, w) } func (m *Manager) Logout(w http.ResponseWriter, r *http.Request) error { sess, _ := m.store.Get(r, SessionName) sess.Values["authenticated"] = false sess.Options.MaxAge = -1 return sess.Save(r, w) } func (m *Manager) IsAuthenticated(r *http.Request) bool { sess, err := m.store.Get(r, SessionName) if err != nil { return false } ok, _ := sess.Values["authenticated"].(bool) return ok } func (m *Manager) CurrentName(r *http.Request) string { sess, err := m.store.Get(r, SessionName) if err != nil { return "" } name, _ := sess.Values["name"].(string) if name != "" { return name } email, _ := sess.Values["email"].(string) return email } func (m *Manager) RequireAuth(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if !m.IsAuthenticated(r) { http.Redirect(w, r, "/login", http.StatusSeeOther) return } next(w, r) } }