From f416775268085c7fb7f90cf54ea2149267b960e6 Mon Sep 17 00:00:00 2001 From: Julian Hurst Date: Wed, 25 Jan 2023 01:23:58 +0100 Subject: Add user impersonation support for admins --- imgs.go | 14 +++++++++++-- main.go | 53 +++++++++++++++++++++++++++++++++++++---------- templates/createuser.html | 2 ++ templates/imgs.html | 8 +++++++ templates/imgs_page.html | 6 ++++++ templates/nav_logged.html | 5 +++++ templates/user.html | 12 +++++++++++ 7 files changed, 87 insertions(+), 13 deletions(-) diff --git a/imgs.go b/imgs.go index 78705ca..4ee448b 100644 --- a/imgs.go +++ b/imgs.go @@ -17,6 +17,13 @@ const pageSize = 5 func imgs(w http.ResponseWriter, r *http.Request) { u, err := checkSession(w, r) if u != nil && err == nil { + username := u.Username + if u.IsAdmin { + name := r.URL.Query().Get("user") + if name != "" { + username = name + } + } fragment := r.URL.Query().Has("fragment") pageQuery := r.URL.Query().Get("page") if pageQuery == "" { @@ -27,7 +34,7 @@ func imgs(w http.ResponseWriter, r *http.Request) { sendError(w, r, err.Error(), http.StatusInternalServerError) return } - userDocPath := filepath.Join(baseDocDir, u.Username) + userDocPath := filepath.Join(baseDocDir, username) err = os.Mkdir(userDocPath, 0750) if err != nil && !os.IsExist(err) { sendError(w, r, err.Error(), http.StatusInternalServerError) @@ -67,6 +74,7 @@ func imgs(w http.ResponseWriter, r *http.Request) { start = len(imgs) } flasherr := consumeFlash(w, r, "error") + userImpersonation := r.URL.Query().Get("user") data := struct { Imgs []Doc Start int @@ -74,6 +82,7 @@ func imgs(w http.ResponseWriter, r *http.Request) { NbFiles int Page int Error string + UserImpersonation string }{ imgs[start:end], start + 1, @@ -81,6 +90,7 @@ func imgs(w http.ResponseWriter, r *http.Request) { len(imgs), page, flasherr, + userImpersonation, } if fragment { //serveSimple(w, r, data, "templates/imgs_stub.html") @@ -92,7 +102,7 @@ func imgs(w http.ResponseWriter, r *http.Request) { } else if err != nil { log.Println(err) } - sendFlash(w, r, "redirect", "/imgs") + sendFlash(w, r, "redirect", r.URL.String()) http.Redirect(w, r, "/login", http.StatusSeeOther) } diff --git a/main.go b/main.go index 6f779e4..863673a 100644 --- a/main.go +++ b/main.go @@ -181,12 +181,19 @@ func humanize(i int64) string { func index(w http.ResponseWriter, r *http.Request) { u, err := checkSession(w, r) if u != nil && err == nil { - userDocPath := filepath.Join(baseDocDir, u.Username) + username := u.Username + if u.IsAdmin { + name := r.URL.Query().Get("user") + if name != "" { + username = name + } + } + userDocPath := filepath.Join(baseDocDir, username) err := os.Mkdir(userDocPath, 0750) if err != nil && !os.IsExist(err) { sendError(w, r, err.Error(), http.StatusInternalServerError) } - files, err := os.ReadDir(filepath.Join(baseDocDir, u.Username)) + files, err := os.ReadDir(filepath.Join(baseDocDir, username)) if err != nil { sendError(w, r, err.Error(), http.StatusInternalServerError) } @@ -212,23 +219,26 @@ func index(w http.ResponseWriter, r *http.Request) { file.Name(), humanize(info.Size()), info.ModTime(), - path.Join(baseDocDir, u.Username, file.Name()), + path.Join(baseDocDir, username, file.Name()), }) } flasherr := consumeFlash(w, r, "error") + userImpersonation := r.URL.Query().Get("user") data := struct { Docs []Doc Error string + UserImpersonation string }{ docs, flasherr, + userImpersonation, } serveTemplate(w, r, data, "templates/user.html") return } else if err != nil { log.Println(err) } - sendFlash(w, r, "redirect", "/") + sendFlash(w, r, "redirect", r.URL.String()) http.Redirect(w, r, "/login", http.StatusSeeOther) } @@ -278,6 +288,7 @@ func createuser(w http.ResponseWriter, r *http.Request) { email := r.FormValue("email") pass := r.FormValue("pass") cpass := r.FormValue("cpass") + isadmin := r.FormValue("isadmin") if len(pass) < 10 { sendFlash(w, r, "error", "Le mot de passe doit avoir une longeur supérieure ou égale à 10 caractères.") http.Redirect(w, r, "/createuser", http.StatusSeeOther) @@ -288,7 +299,7 @@ func createuser(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/createuser", http.StatusSeeOther) return } - user := User{-1, u, email, pass, false} + user := User{-1, u, email, pass, isadmin == "on"} user, err := CreateUser(db, user) if err != nil { sendError(w, r, err.Error(), http.StatusInternalServerError) @@ -405,7 +416,7 @@ func handleFileServer(dir, prefix string) http.HandlerFunc { if u != nil && err == nil { dir := filepath.Dir(r.URL.Path) username := filepath.Base(dir) - if u.Username == username { + if u.Username == username || u.IsAdmin { hdlr(w, r) return } @@ -417,6 +428,13 @@ func handleFileServer(dir, prefix string) http.HandlerFunc { func download(w http.ResponseWriter, r *http.Request) { u, err := checkSession(w, r) if u != nil && err == nil { + username := u.Username + if u.IsAdmin { + name := r.URL.Query().Get("user") + if name != "" { + username = name + } + } switch r.Method { case http.MethodPost: r.ParseForm() @@ -431,7 +449,7 @@ func download(w http.ResponseWriter, r *http.Request) { wr := zip.NewWriter(w) defer wr.Close() for _, sel := range selection { - if filepath.Base(filepath.Dir(sel)) == u.Username { + if filepath.Base(filepath.Dir(sel)) == username { wrc, err := wr.Create(filepath.Base(sel)) if err != nil { sendError(w, r, err.Error(), http.StatusInternalServerError) @@ -450,13 +468,13 @@ func download(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Disposition", contentDisposition) wr := zip.NewWriter(w) defer wr.Close() - files, err := os.ReadDir(filepath.Join(baseDocDir, u.Username)) + files, err := os.ReadDir(filepath.Join(baseDocDir, username)) if err != nil { sendError(w, r, err.Error(), http.StatusInternalServerError) return } for _, file := range files { - filePath := path.Join(baseDocDir, u.Username, file.Name()) + filePath := path.Join(baseDocDir, username, file.Name()) wrc, err := wr.Create(filepath.Base(filePath)) if err != nil { sendError(w, r, err.Error(), http.StatusInternalServerError) @@ -482,7 +500,16 @@ func upload(w http.ResponseWriter, r *http.Request) { case http.MethodPost: u, err := checkSession(w, r) if u != nil && err == nil { - userDocPath := filepath.Join(baseDocDir, u.Username) + userImpersonation := false + username := u.Username + if u.IsAdmin { + name := r.URL.Query().Get("user") + if name != "" { + username = name + userImpersonation = true + } + } + userDocPath := filepath.Join(baseDocDir, username) err := os.Mkdir(userDocPath, 0750) if err != nil && !os.IsExist(err) { sendError(w, r, err.Error(), http.StatusInternalServerError) @@ -509,7 +536,11 @@ func upload(w http.ResponseWriter, r *http.Request) { sendError(w, r, err.Error(), http.StatusInternalServerError) } } - http.Redirect(w, r, "/", http.StatusSeeOther) + if userImpersonation { + http.Redirect(w, r, fmt.Sprintf("/?user=%s", username), http.StatusSeeOther) + } else { + http.Redirect(w, r, "/", http.StatusSeeOther) + } } else { http.Redirect(w, r, "/login", http.StatusSeeOther) } diff --git a/templates/createuser.html b/templates/createuser.html index ee4858b..92a1b22 100644 --- a/templates/createuser.html +++ b/templates/createuser.html @@ -10,6 +10,8 @@





+ +

{{end}} diff --git a/templates/imgs.html b/templates/imgs.html index e747034..51b489d 100644 --- a/templates/imgs.html +++ b/templates/imgs.html @@ -4,13 +4,21 @@ {{template "imgspage" .}}
{{.NbFiles}} images diff --git a/templates/imgs_page.html b/templates/imgs_page.html index 665daf3..3f1ce58 100644 --- a/templates/imgs_page.html +++ b/templates/imgs_page.html @@ -1,9 +1,15 @@ {{define "imgspage"}} {{range $i, $img := .Imgs}} {{if eq (add $i $.Start) $.End}} + {{if ne $.UserImpersonation ""}} +
+ {{else}}
+ {{end}} {{$img.Name}}

{{else}} diff --git a/templates/nav_logged.html b/templates/nav_logged.html index 50e9a36..06c7a21 100644 --- a/templates/nav_logged.html +++ b/templates/nav_logged.html @@ -2,8 +2,13 @@ diff --git a/templates/user.html b/templates/user.html index cd0d98c..9a3a333 100644 --- a/templates/user.html +++ b/templates/user.html @@ -5,11 +5,19 @@ {{if .Error}}

{{.Error}}

{{end}} + {{if ne .UserImpersonation ""}} +
+ {{else}} + {{end}}
+ {{if ne .UserImpersonation ""}} +
+ {{else}} + {{end}}
@@ -39,7 +47,11 @@
+ {{if ne .UserImpersonation ""}} + + {{else}} + {{end}} {{end}} -- cgit v1.2.3