A bunch of fixes
This commit is contained in:
1 parent
65534ecfd5
commit
2a4e03e611
20 files changed
+146
-160
No files matched your search
@@ -15,22 +15,14 @@ import (
|
||||
"uPortal/internal/user"
|
||||
)
|
||||
|
||||
// Cookie names and the CSRF form field name. These match the layout
|
||||
// template (templates/layouts/csrf.html) and the auth package helpers.
|
||||
const (
|
||||
SessionCookieName = "sessiontoken"
|
||||
CsrfCookieName = "csrftoken"
|
||||
CsrfFieldName = "formtoken"
|
||||
)
|
||||
|
||||
// CookieSecure controls the Secure attribute of the session cookie.
|
||||
// It is disabled by default so the app works over plain http://127.0.0.1
|
||||
// during development (browsers drop Secure cookies over plain http).
|
||||
// Production deployments behind HTTPS must flip this to true.
|
||||
var CookieSecure = false
|
||||
|
||||
// ViewData is the data bag passed to every page template. It carries the
|
||||
// CSRF token, the current user, and any collections the pages display.
|
||||
type ViewData struct {
|
||||
Title string
|
||||
IsSuperUser bool
|
||||
@@ -53,7 +45,6 @@ type WebService struct {
|
||||
log *log.Logger
|
||||
}
|
||||
|
||||
// New returns a WebService ready to be registered onto an http.ServeMux.
|
||||
func New(users *user.Repository, auths *auth.Repository, views *template.Service, db *sql.DB, jitsiCfg *jitsi.Config, trustedDomains []string, logger *log.Logger) *WebService {
|
||||
return &WebService{
|
||||
users: users,
|
||||
@@ -66,11 +57,7 @@ func New(users *user.Repository, auths *auth.Repository, views *template.Service
|
||||
}
|
||||
}
|
||||
|
||||
// isTrustedTarget reports whether target may skip the /redirect warning page.
|
||||
// Relative paths, empty hostnames and unknown hosts are never trusted;
|
||||
// localhost and 127.0.0.1 are always trusted.
|
||||
func (s *WebService) isTrustedTarget(target string) bool {
|
||||
// Handle URLs without a scheme (e.g. "meet.jit.si/room").
|
||||
if !strings.Contains(target, "://") {
|
||||
target = "https://" + target
|
||||
}
|
||||
@@ -80,7 +67,6 @@ func (s *WebService) isTrustedTarget(target string) bool {
|
||||
}
|
||||
host := u.Hostname()
|
||||
|
||||
// Loopback addresses are always trusted for full URL redirects.
|
||||
if host == "localhost" || host == "127.0.0.1" {
|
||||
return true
|
||||
}
|
||||
@@ -95,7 +81,6 @@ func (s *WebService) isTrustedTarget(target string) bool {
|
||||
|
||||
// Register wires every route (method + path) onto the mux.
|
||||
func (s *WebService) Register(mux *http.ServeMux) {
|
||||
// Helper to wrap every handler with logging middleware.
|
||||
handle := func(pattern string, handler http.HandlerFunc) {
|
||||
mux.HandleFunc(pattern, s.loggingMiddleware(handler))
|
||||
}
|
||||
@@ -152,15 +137,12 @@ func (s *WebService) Register(mux *http.ServeMux) {
|
||||
// loggingMiddleware logs every HTTP request. Static file endpoints are skipped.
|
||||
func (s *WebService) loggingMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// Skip logging for static files and health checks.
|
||||
if strings.HasPrefix(r.URL.Path, "/static/") {
|
||||
next(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
|
||||
// Wrap the ResponseWriter to capture the status code.
|
||||
lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK}
|
||||
next(lrw, r)
|
||||
|
||||
@@ -185,9 +167,6 @@ func (lrw *loggingResponseWriter) WriteHeader(code int) {
|
||||
lrw.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
|
||||
// render fills ViewData defaults and writes the response.
|
||||
// If data.FormToken is empty (e.g. for call sites that don't use
|
||||
// basicViewData), a CSRF token is minted as a fallback.
|
||||
func (s *WebService) render(w http.ResponseWriter, r *http.Request, page string, data *ViewData) {
|
||||
if data == nil {
|
||||
data = &ViewData{}
|
||||
@@ -212,7 +191,6 @@ func (s *WebService) render(w http.ResponseWriter, r *http.Request, page string,
|
||||
}
|
||||
}
|
||||
|
||||
// getUserInfo reads the session cookie and looks up the associated user.
|
||||
func (s *WebService) getUserInfo(r *http.Request) (*user.User, error) {
|
||||
cookie, err := r.Cookie(SessionCookieName)
|
||||
if err != nil {
|
||||
@@ -232,7 +210,6 @@ func (s *WebService) currentUser(r *http.Request) (*user.User, error) {
|
||||
return s.getUserInfo(r)
|
||||
}
|
||||
|
||||
// basicViewData builds a ViewData with the current user and CSRF token.
|
||||
func (s *WebService) basicViewData(w http.ResponseWriter, r *http.Request, title string) (*ViewData, bool) {
|
||||
user, err := s.getUserInfo(r)
|
||||
if err != nil {
|
||||
@@ -245,8 +222,6 @@ func (s *WebService) basicViewData(w http.ResponseWriter, r *http.Request, title
|
||||
return &ViewData{Title: title, User: user, IsSuperUser: user.SuperUser, FormToken: token}, true
|
||||
}
|
||||
|
||||
// requireAuth redirects unauthenticated visitors to /signin with a ?redirect=
|
||||
// parameter so they return to their intended page after login.
|
||||
func (s *WebService) requireAuth(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if _, err := s.currentUser(r); err != nil {
|
||||
@@ -261,7 +236,6 @@ func (s *WebService) requireAuth(next http.HandlerFunc) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// requireSuperUser wraps a handler, requiring an authenticated super user.
|
||||
func (s *WebService) requireSuperUser(next http.HandlerFunc) http.HandlerFunc {
|
||||
return s.requireAuth(func(w http.ResponseWriter, r *http.Request) {
|
||||
u, err := s.currentUser(r)
|
||||
|
||||
Reference in new issue
Block a user