fixed viewing invisible releases with admin session

This commit is contained in:
ari melody 2025-01-27 00:27:03 +00:00
parent 1efe52a8cb
commit 70825ae875
Signed by: ari
GPG key ID: CF99829C92678188
5 changed files with 46 additions and 36 deletions

View file

@ -477,30 +477,13 @@ func staticHandler() http.Handler {
func enforceSession(app *model.AppState, next http.Handler) http.Handler { func enforceSession(app *model.AppState, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sessionCookie, err := r.Cookie(model.COOKIE_TOKEN) session, err := controller.GetSessionFromRequest(app.DB, r)
if err != nil && err != http.ErrNoCookie { if err != nil {
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session cookie: %v\n", err) fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session: %v\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
var session *model.Session
if sessionCookie != nil {
// fetch existing session
session, err = controller.GetSession(app.DB, sessionCookie.Value)
if err != nil && !strings.Contains(err.Error(), "no rows") {
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session: %v\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
if session != nil {
// TODO: consider running security checks here (i.e. user agent mismatches)
}
}
if session == nil { if session == nil {
// create a new session // create a new session
session, err = controller.CreateSession(app.DB, r.UserAgent()) session, err = controller.CreateSession(app.DB, r.UserAgent())

View file

@ -19,7 +19,13 @@ func ServeRelease(app *model.AppState, release *model.Release) http.Handler {
// only allow authorised users to view hidden releases // only allow authorised users to view hidden releases
privileged := false privileged := false
if !release.Visible { if !release.Visible {
session := r.Context().Value("session").(*model.Session) session, err := controller.GetSessionFromRequest(app.DB, r)
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session: %v\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
if session != nil && session.Account != nil { if session != nil && session.Account != nil {
// TODO: check privilege on release // TODO: check privilege on release
privileged = true privileged = true

View file

@ -2,7 +2,6 @@ package controller
import ( import (
"arimelody-web/model" "arimelody-web/model"
"net/http"
"strings" "strings"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
@ -77,19 +76,6 @@ func GetAccountBySession(db *sqlx.DB, sessionToken string) (*model.Account, erro
return &account, nil return &account, nil
} }
func GetSessionFromRequest(db *sqlx.DB, r *http.Request) string {
tokenStr := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
if len(tokenStr) > 0 {
return tokenStr
}
cookie, err := r.Cookie(model.COOKIE_TOKEN)
if err != nil {
return ""
}
return cookie.Value
}
func CreateAccount(db *sqlx.DB, account *model.Account) error { func CreateAccount(db *sqlx.DB, account *model.Account) error {
err := db.Get( err := db.Get(
&account.ID, &account.ID,

View file

@ -2,6 +2,10 @@ package controller
import ( import (
"database/sql" "database/sql"
"errors"
"fmt"
"net/http"
"strings"
"time" "time"
"arimelody-web/model" "arimelody-web/model"
@ -11,6 +15,30 @@ import (
const TOKEN_LEN = 64 const TOKEN_LEN = 64
func GetSessionFromRequest(db *sqlx.DB, r *http.Request) (*model.Session, error) {
sessionCookie, err := r.Cookie(model.COOKIE_TOKEN)
if err != nil && err != http.ErrNoCookie {
return nil, errors.New(fmt.Sprintf("Failed to retrieve session cookie: %v", err))
}
var session *model.Session
if sessionCookie != nil {
// fetch existing session
session, err = GetSession(db, sessionCookie.Value)
if err != nil && !strings.Contains(err.Error(), "no rows") {
return nil, errors.New(fmt.Sprintf("Failed to retrieve session: %v", err))
}
if session != nil {
// TODO: consider running security checks here (i.e. user agent mismatches)
}
}
return session, nil
}
func CreateSession(db *sqlx.DB, userAgent string) (*model.Session, error) { func CreateSession(db *sqlx.DB, userAgent string) (*model.Session, error) {
tokenString := GenerateAlnumString(TOKEN_LEN) tokenString := GenerateAlnumString(TOKEN_LEN)

View file

@ -3,6 +3,7 @@ package view
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"os"
"arimelody-web/controller" "arimelody-web/controller"
"arimelody-web/model" "arimelody-web/model"
@ -59,7 +60,13 @@ func ServeGateway(app *model.AppState, release *model.Release) http.Handler {
// only allow authorised users to view hidden releases // only allow authorised users to view hidden releases
privileged := false privileged := false
if !release.Visible { if !release.Visible {
session := r.Context().Value("session").(*model.Session) session, err := controller.GetSessionFromRequest(app.DB, r)
if err != nil {
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session: %v\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
if session != nil && session.Account != nil { if session != nil && session.Account != nil {
// TODO: check privilege on release // TODO: check privilege on release
privileged = true privileged = true