Remove session library

This commit is contained in:
Melon 2024-02-15 15:09:14 +00:00
parent 894149305b
commit 374a708899
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
9 changed files with 58 additions and 92 deletions

5
go.mod
View File

@ -9,14 +9,13 @@ require (
github.com/1f349/violet v0.0.13 github.com/1f349/violet v0.0.13
github.com/MrMelon54/exit-reload v0.0.1 github.com/MrMelon54/exit-reload v0.0.1
github.com/go-oauth2/oauth2/v4 v4.5.2 github.com/go-oauth2/oauth2/v4 v4.5.2
github.com/go-session/session v3.1.2+incompatible
github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/subcommands v1.2.0 github.com/google/subcommands v1.2.0
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/julienschmidt/httprouter v1.3.0 github.com/julienschmidt/httprouter v1.3.0
github.com/mattn/go-sqlite3 v1.14.22 github.com/mattn/go-sqlite3 v1.14.22
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
golang.org/x/oauth2 v0.16.0 golang.org/x/oauth2 v0.17.0
) )
require ( require (
@ -30,7 +29,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/tidwall/btree v1.7.0 // indirect github.com/tidwall/btree v1.7.0 // indirect
github.com/tidwall/buntdb v1.3.0 // indirect github.com/tidwall/buntdb v1.3.0 // indirect
github.com/tidwall/gjson v1.17.0 // indirect github.com/tidwall/gjson v1.17.1 // indirect
github.com/tidwall/grect v0.1.4 // indirect github.com/tidwall/grect v0.1.4 // indirect
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect

9
go.sum
View File

@ -30,7 +30,6 @@ github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
github.com/go-oauth2/oauth2/v4 v4.5.2 h1:CuZhD3lhGuI6aNLyUbRHXsgG2RwGRBOuCBfd4WQKqBQ= github.com/go-oauth2/oauth2/v4 v4.5.2 h1:CuZhD3lhGuI6aNLyUbRHXsgG2RwGRBOuCBfd4WQKqBQ=
github.com/go-oauth2/oauth2/v4 v4.5.2/go.mod h1:wk/2uLImWIa9VVQDgxz99H2GDbhmfi/9/Xr+GvkSUSQ= github.com/go-oauth2/oauth2/v4 v4.5.2/go.mod h1:wk/2uLImWIa9VVQDgxz99H2GDbhmfi/9/Xr+GvkSUSQ=
github.com/go-session/session v3.1.2+incompatible h1:yStchEObKg4nk2F7JGE7KoFIrA/1Y078peagMWcrncg=
github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0= github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
@ -125,8 +124,8 @@ github.com/tidwall/buntdb v1.3.0 h1:gdhWO+/YwoB2qZMeAU9JcWWsHSYU3OvcieYgFRS0zwA=
github.com/tidwall/buntdb v1.3.0/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU= github.com/tidwall/buntdb v1.3.0/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU=
github.com/tidwall/gjson v1.3.4/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= github.com/tidwall/gjson v1.3.4/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb/go.mod h1:lKYYLFIr9OIgdgrtgkZ9zgRxRdvPYsExnYBsEAd8W5M= github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb/go.mod h1:lKYYLFIr9OIgdgrtgkZ9zgRxRdvPYsExnYBsEAd8W5M=
github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg= github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg=
github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q= github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q=
@ -182,8 +181,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View File

@ -1,9 +1,9 @@
package server package server
import ( import (
"fmt"
"github.com/1f349/lavender/database" "github.com/1f349/lavender/database"
"github.com/go-session/session" "github.com/1f349/mjwt"
"github.com/1f349/mjwt/auth"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"net/http" "net/http"
"net/url" "net/url"
@ -13,30 +13,18 @@ import (
type UserHandler func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, auth UserAuth) type UserHandler func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, auth UserAuth)
type UserAuth struct { type UserAuth struct {
Session session.Store
Data SessionData
}
type SessionData struct {
ID string ID string
DisplayName string DisplayName string
UserInfo UserInfoFields UserInfo UserInfoFields
} }
func (u UserAuth) IsGuest() bool { func (u UserAuth) IsGuest() bool { return u.ID == "" }
return u.Data.ID == ""
}
func (u UserAuth) SaveSessionData() error {
u.Session.Set("session-data", u.Data)
return u.Session.Save()
}
func (h *HttpServer) RequireAdminAuthentication(next UserHandler) httprouter.Handle { func (h *HttpServer) RequireAdminAuthentication(next UserHandler) httprouter.Handle {
return h.RequireAuthentication(func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, auth UserAuth) { return h.RequireAuthentication(func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, auth UserAuth) {
var roles string var roles string
if h.DbTx(rw, func(tx *database.Tx) (err error) { if h.DbTx(rw, func(tx *database.Tx) (err error) {
roles, err = tx.GetUserRoles(auth.Data.ID) roles, err = tx.GetUserRoles(auth.ID)
return return
}) { }) {
return return
@ -62,7 +50,7 @@ func (h *HttpServer) RequireAuthentication(next UserHandler) httprouter.Handle {
func (h *HttpServer) OptionalAuthentication(next UserHandler) httprouter.Handle { func (h *HttpServer) OptionalAuthentication(next UserHandler) httprouter.Handle {
return func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) { return func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
auth, err := internalAuthenticationHandler(rw, req) auth, err := h.internalAuthenticationHandler(req)
if err != nil { if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError) http.Error(rw, err.Error(), http.StatusInternalServerError)
return return
@ -75,27 +63,16 @@ func (h *HttpServer) OptionalAuthentication(next UserHandler) httprouter.Handle
} }
} }
func internalAuthenticationHandler(rw http.ResponseWriter, req *http.Request) (UserAuth, error) { func (h *HttpServer) internalAuthenticationHandler(req *http.Request) (UserAuth, error) {
ss, err := session.Start(req.Context(), rw, req) if loginCookie, err := req.Cookie("tulip-login-data"); err == nil {
_, b, err := mjwt.ExtractClaims[auth.AccessTokenClaims](h.signingKey, loginCookie.Value)
if err != nil { if err != nil {
return UserAuth{}, fmt.Errorf("failed to start session") return UserAuth{}, err
} }
return UserAuth{ID: b.Subject}, nil
// get auth object
userIdRaw, ok := ss.Get("session-data")
if !ok {
return UserAuth{Session: ss}, nil
} }
userData, ok := userIdRaw.(SessionData) // not logged in
if !ok { return UserAuth{}, nil
ss.Delete("session-data")
err := ss.Save()
if err != nil {
return UserAuth{Session: ss}, fmt.Errorf("failed to reset invalid session data")
}
}
return UserAuth{Session: ss, Data: userData}, nil
} }
func PrepareRedirectUrl(targetPath string, origin *url.URL) *url.URL { func PrepareRedirectUrl(targetPath string, origin *url.URL) *url.URL {

View File

@ -6,10 +6,21 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"net/http" "net/http"
"time"
) )
func (h *HttpServer) Home(rw http.ResponseWriter, _ *http.Request, _ httprouter.Params, auth UserAuth) { func (h *HttpServer) Home(rw http.ResponseWriter, _ *http.Request, _ httprouter.Params, auth UserAuth) {
rw.Header().Set("Content-Type", "text/html") rw.Header().Set("Content-Type", "text/html")
lNonce := uuid.NewString()
http.SetCookie(rw, &http.Cookie{
Name: "tulip-nonce",
Value: lNonce,
Path: "/",
Expires: time.Now().Add(10 * time.Minute),
Secure: true,
SameSite: http.SameSiteLaxMode,
})
if auth.IsGuest() { if auth.IsGuest() {
pages.RenderPageTemplate(rw, "index-guest", map[string]any{ pages.RenderPageTemplate(rw, "index-guest", map[string]any{
"ServiceName": h.conf.ServiceName, "ServiceName": h.conf.ServiceName,
@ -19,23 +30,16 @@ func (h *HttpServer) Home(rw http.ResponseWriter, _ *http.Request, _ httprouter.
var isAdmin bool var isAdmin bool
h.DbTx(rw, func(tx *database.Tx) (err error) { h.DbTx(rw, func(tx *database.Tx) (err error) {
roles, err := tx.GetUserRoles(auth.Data.ID) roles, err := tx.GetUserRoles(auth.ID)
isAdmin = HasRole(roles, "lavender:admin") isAdmin = HasRole(roles, "lavender:admin")
return err return err
}) })
lNonce := uuid.NewString()
auth.Session.Set("action-nonce", lNonce)
if auth.Session.Save() != nil {
http.Error(rw, "Failed to save session", http.StatusInternalServerError)
return
}
pages.RenderPageTemplate(rw, "index", map[string]any{ pages.RenderPageTemplate(rw, "index", map[string]any{
"ServiceName": h.conf.ServiceName, "ServiceName": h.conf.ServiceName,
"Auth": auth, "Auth": auth,
"Subject": auth.Data.ID, "Subject": auth.ID,
"DisplayName": auth.Data.DisplayName, "DisplayName": auth.DisplayName,
"Nonce": lNonce, "Nonce": lNonce,
"IsAdmin": isAdmin, "IsAdmin": isAdmin,
}) })

View File

@ -127,19 +127,15 @@ func (h *HttpServer) loginCallback(rw http.ResponseWriter, req *http.Request, _
} }
// only continues if the above tx succeeds // only continues if the above tx succeeds
auth.Data = sessionData auth = sessionData
if err := auth.SaveSessionData(); err != nil {
http.Error(rw, "Failed to save session", http.StatusInternalServerError)
return
}
if h.DbTx(rw, func(tx *database.Tx) error { if h.DbTx(rw, func(tx *database.Tx) error {
return tx.UpdateUserToken(auth.Data.ID, token.AccessToken, token.RefreshToken, token.Expiry) return tx.UpdateUserToken(auth.ID, token.AccessToken, token.RefreshToken, token.Expiry)
}) { }) {
return return
} }
if h.setLoginDataCookie(rw, auth.Data.ID) { if h.setLoginDataCookie(rw, auth.ID) {
http.Error(rw, "Failed to save login cookie", http.StatusInternalServerError) http.Error(rw, "Failed to save login cookie", http.StatusInternalServerError)
return return
} }
@ -193,28 +189,28 @@ func (h *HttpServer) readLoginDataCookie(req *http.Request, u *UserAuth) {
return return
} }
u.Data, _ = h.fetchUserInfo(sso, &token) *u, _ = h.fetchUserInfo(sso, &token)
} }
func (h *HttpServer) fetchUserInfo(sso *issuer.WellKnownOIDC, token *oauth2.Token) (SessionData, error) { func (h *HttpServer) fetchUserInfo(sso *issuer.WellKnownOIDC, token *oauth2.Token) (UserAuth, error) {
res, err := sso.OAuth2Config.Client(context.Background(), token).Get(sso.UserInfoEndpoint) res, err := sso.OAuth2Config.Client(context.Background(), token).Get(sso.UserInfoEndpoint)
if err != nil || res.StatusCode != http.StatusOK { if err != nil || res.StatusCode != http.StatusOK {
return SessionData{}, fmt.Errorf("request failed") return UserAuth{}, fmt.Errorf("request failed")
} }
defer res.Body.Close() defer res.Body.Close()
var userInfoJson UserInfoFields var userInfoJson UserInfoFields
if err := json.NewDecoder(res.Body).Decode(&userInfoJson); err != nil { if err := json.NewDecoder(res.Body).Decode(&userInfoJson); err != nil {
return SessionData{}, err return UserAuth{}, err
} }
subject, ok := userInfoJson.GetString("sub") subject, ok := userInfoJson.GetString("sub")
if !ok { if !ok {
return SessionData{}, fmt.Errorf("invalid subject") return UserAuth{}, fmt.Errorf("invalid subject")
} }
subject += "@" + sso.Config.Namespace subject += "@" + sso.Config.Namespace
displayName := userInfoJson.GetStringOrDefault("name", "Unknown Name") displayName := userInfoJson.GetStringOrDefault("name", "Unknown Name")
return SessionData{ return UserAuth{
ID: subject, ID: subject,
DisplayName: displayName, DisplayName: displayName,
UserInfo: userInfoJson, UserInfo: userInfoJson,

View File

@ -26,11 +26,11 @@ func (h *HttpServer) ManageAppsGet(rw http.ResponseWriter, req *http.Request, _
var roles string var roles string
var appList []database.ClientInfoDbOutput var appList []database.ClientInfoDbOutput
if h.DbTx(rw, func(tx *database.Tx) (err error) { if h.DbTx(rw, func(tx *database.Tx) (err error) {
roles, err = tx.GetUserRoles(auth.Data.ID) roles, err = tx.GetUserRoles(auth.ID)
if err != nil { if err != nil {
return return
} }
appList, err = tx.GetAppList(auth.Data.ID, HasRole(roles, "lavender:admin"), offset) appList, err = tx.GetAppList(auth.ID, HasRole(roles, "lavender:admin"), offset)
return return
}) { }) {
return return
@ -80,7 +80,7 @@ func (h *HttpServer) ManageAppsPost(rw http.ResponseWriter, req *http.Request, _
if sso || hasPerms { if sso || hasPerms {
var roles string var roles string
if h.DbTx(rw, func(tx *database.Tx) (err error) { if h.DbTx(rw, func(tx *database.Tx) (err error) {
roles, err = tx.GetUserRoles(auth.Data.ID) roles, err = tx.GetUserRoles(auth.ID)
return return
}) { }) {
return return
@ -98,7 +98,7 @@ func (h *HttpServer) ManageAppsPost(rw http.ResponseWriter, req *http.Request, _
switch action { switch action {
case "create": case "create":
if h.DbTx(rw, func(tx *database.Tx) error { if h.DbTx(rw, func(tx *database.Tx) error {
return tx.InsertClientApp(name, domain, auth.Data.ID, perms, public, sso, active) return tx.InsertClientApp(name, domain, auth.ID, perms, public, sso, active)
}) { }) {
return return
} }
@ -108,7 +108,7 @@ func (h *HttpServer) ManageAppsPost(rw http.ResponseWriter, req *http.Request, _
if err != nil { if err != nil {
return err return err
} }
return tx.UpdateClientApp(sub, auth.Data.ID, name, domain, perms, hasPerms, public, sso, active) return tx.UpdateClientApp(sub, auth.ID, name, domain, perms, hasPerms, public, sso, active)
}) { }) {
return return
} }
@ -124,7 +124,7 @@ func (h *HttpServer) ManageAppsPost(rw http.ResponseWriter, req *http.Request, _
if err != nil { if err != nil {
return err return err
} }
secret, err = tx.ResetClientAppSecret(sub, auth.Data.ID) secret, err = tx.ResetClientAppSecret(sub, auth.ID)
return err return err
}) { }) {
return return

View File

@ -24,7 +24,7 @@ func (h *HttpServer) ManageUsersGet(rw http.ResponseWriter, req *http.Request, _
var roles string var roles string
var userList []database.User var userList []database.User
if h.DbTx(rw, func(tx *database.Tx) (err error) { if h.DbTx(rw, func(tx *database.Tx) (err error) {
roles, err = tx.GetUserRoles(auth.Data.ID) roles, err = tx.GetUserRoles(auth.ID)
if err != nil { if err != nil {
return return
} }
@ -43,7 +43,7 @@ func (h *HttpServer) ManageUsersGet(rw http.ResponseWriter, req *http.Request, _
"Users": userList, "Users": userList,
"Offset": offset, "Offset": offset,
"EmailShow": req.URL.Query().Has("show-email"), "EmailShow": req.URL.Query().Has("show-email"),
"CurrentAdmin": auth.Data.ID, "CurrentAdmin": auth.ID,
} }
if q.Has("edit") { if q.Has("edit") {
for _, i := range userList { for _, i := range userList {
@ -71,7 +71,7 @@ func (h *HttpServer) ManageUsersPost(rw http.ResponseWriter, req *http.Request,
var roles string var roles string
if h.DbTx(rw, func(tx *database.Tx) (err error) { if h.DbTx(rw, func(tx *database.Tx) (err error) {
roles, err = tx.GetUserRoles(auth.Data.ID) roles, err = tx.GetUserRoles(auth.ID)
return return
}) { }) {
return return

View File

@ -87,7 +87,7 @@ func (h *HttpServer) authorizeEndpoint(rw http.ResponseWriter, req *http.Request
"ServiceName": h.conf.ServiceName, "ServiceName": h.conf.ServiceName,
"AppName": appName, "AppName": appName,
"AppDomain": appDomain, "AppDomain": appDomain,
"DisplayName": auth.Data.DisplayName, "DisplayName": auth.DisplayName,
"WantsList": scope.FancyScopeList(scopeList), "WantsList": scope.FancyScopeList(scopeList),
"ResponseType": form.Get("response_type"), "ResponseType": form.Get("response_type"),
"ResponseMode": form.Get("response_mode"), "ResponseMode": form.Get("response_mode"),
@ -125,7 +125,7 @@ func (h *HttpServer) oauthUserAuthorization(rw http.ResponseWriter, req *http.Re
return "", err return "", err
} }
auth, err := internalAuthenticationHandler(rw, req) auth, err := h.internalAuthenticationHandler(req)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -147,5 +147,5 @@ func (h *HttpServer) oauthUserAuthorization(rw http.ResponseWriter, req *http.Re
http.Redirect(rw, req, redirectUrl.String(), http.StatusFound) http.Redirect(rw, req, redirectUrl.String(), http.StatusFound)
return "", nil return "", nil
} }
return auth.Data.ID, nil return auth.ID, nil
} }

View File

@ -17,7 +17,6 @@ import (
"github.com/go-oauth2/oauth2/v4/manage" "github.com/go-oauth2/oauth2/v4/manage"
"github.com/go-oauth2/oauth2/v4/server" "github.com/go-oauth2/oauth2/v4/server"
"github.com/go-oauth2/oauth2/v4/store" "github.com/go-oauth2/oauth2/v4/store"
"github.com/go-session/session"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"log" "log"
@ -46,8 +45,6 @@ type flowStateData struct {
} }
func NewHttpServer(conf Conf, db *database.DB, signingKey mjwt.Signer) *http.Server { func NewHttpServer(conf Conf, db *database.DB, signingKey mjwt.Signer) *http.Server {
session.InitManager(session.SetCookieName("lavender_session"))
r := httprouter.New() r := httprouter.New()
// remove last slash from baseUrl // remove last slash from baseUrl
@ -126,20 +123,14 @@ func NewHttpServer(conf Conf, db *database.DB, signingKey mjwt.Signer) *http.Ser
r.POST("/login", hs.OptionalAuthentication(hs.loginPost)) r.POST("/login", hs.OptionalAuthentication(hs.loginPost))
r.GET("/callback", hs.OptionalAuthentication(hs.loginCallback)) r.GET("/callback", hs.OptionalAuthentication(hs.loginCallback))
r.POST("/logout", hs.RequireAuthentication(func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, auth UserAuth) { r.POST("/logout", hs.RequireAuthentication(func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, auth UserAuth) {
lNonce, ok := auth.Session.Get("action-nonce") cookie, err := req.Cookie("tulip-nonce")
if !ok { if err != nil {
http.Error(rw, "Missing nonce", http.StatusInternalServerError) http.Error(rw, "Missing nonce", http.StatusBadRequest)
return return
} }
if subtle.ConstantTimeCompare([]byte(lNonce.(string)), []byte(req.PostFormValue("nonce"))) == 1 { if subtle.ConstantTimeCompare([]byte(cookie.Value), []byte(req.PostFormValue("nonce"))) == 1 {
auth.Session.Delete("session-data")
if auth.Session.Save() != nil {
http.Error(rw, "Failed to save session", http.StatusInternalServerError)
return
}
http.SetCookie(rw, &http.Cookie{ http.SetCookie(rw, &http.Cookie{
Name: "lavender-login-data", Name: "tulip-login-data",
Path: "/", Path: "/",
MaxAge: -1, MaxAge: -1,
Secure: true, Secure: true,