aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hurst <ark@mansus.space>2023-01-25 01:23:58 +0100
committerJulian Hurst <ark@mansus.space>2023-01-25 01:23:58 +0100
commitf416775268085c7fb7f90cf54ea2149267b960e6 (patch)
treed7e38e94795368f39cda882cd61c16b01eb56dd3
parente7a3649280d20d9b4f68572721684a01049ec40f (diff)
downloaddocspace-f416775268085c7fb7f90cf54ea2149267b960e6.tar.gz
Add user impersonation support for admins
-rw-r--r--imgs.go14
-rw-r--r--main.go53
-rw-r--r--templates/createuser.html2
-rw-r--r--templates/imgs.html8
-rw-r--r--templates/imgs_page.html6
-rw-r--r--templates/nav_logged.html5
-rw-r--r--templates/user.html12
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 @@
<input required type="email" name="email" id="email" placeholder="Email"><br/><br/>
<input required type="password" name="pass" id="pass" placeholder="Mot de passe" minlength="10"><br/><br/>
<input required type="password" name="cpass" id="cpass" placeholder="Confirmation du mot de passe" minlength="10"><br/><br/>
+ <label for="isadmin">Admin?</label>
+ <input type="checkbox" name="isadmin" id="isadmin"><br/><br/>
<input type="submit" value="Créer">
</form>
{{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" .}}
<noscript>
{{if ne .Page 0}}
+ {{if ne .UserImpersonation ""}}
+ <a href="/imgs?page={{add .Page -1}}&user={{.UserImpersonation}}">Previous page</a>
+ {{else}}
<a href="/imgs?page={{add .Page -1}}">Previous page</a>
+ {{end}}
{{if lt .End .NbFiles}}
|
{{end}}
{{end}}
{{if lt .End .NbFiles}}
+ {{if ne .UserImpersonation ""}}
+ <a href="/imgs?page={{add .Page 1}}&user={{.UserImpersonation}}">Next page</a>
+ {{else}}
<a href="/imgs?page={{add .Page 1}}">Next page</a>
+ {{end}}
{{end}}
</noscript>
<br/><span>{{.NbFiles}} images</span>
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 ""}}
+ <div hx-get="/imgs?page={{add $.Page 1}}&fragment&user={{$.UserImpersonation}}"
+ hx-trigger="revealed"
+ hx-swap="afterend">
+ {{else}}
<div hx-get="/imgs?page={{add $.Page 1}}&fragment"
hx-trigger="revealed"
hx-swap="afterend">
+ {{end}}
<span>{{$img.Name}}</span><br/>
<a href="{{$img.Link}}"><img src="{{$img.Link}}" /></a><br/>
{{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 @@
<nav>
<ul class="navlogged">
<!--<li><a href="/admin">Admin</a></li>-->
+ {{if .UserImpersonation}}
+ <li><a href="/?user={{.UserImpersonation}}">Accueil</a></li>
+ <li><a href="/imgs?user={{.UserImpersonation}}">Images</a></li>
+ {{else}}
<li><a href="/">Accueil</a></li>
<li><a href="/imgs">Images</a></li>
+ {{end}}
<li><a href="/logout">Se déconnecter</a></li>
</ul>
</nav>
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}}
<p class="error">{{.Error}}</p>
{{end}}
+ {{if ne .UserImpersonation ""}}
+ <form action="/upload?user={{.UserImpersonation}}" method="POST" enctype="multipart/form-data">
+ {{else}}
<form action="/upload" method="POST" enctype="multipart/form-data">
+ {{end}}
<input type="file" name="files" multiple />
<input type="submit" value="Upload" />
</form>
+ {{if ne .UserImpersonation ""}}
+ <form action="/download?user={{.UserImpersonation}}" method="POST" class="inline">
+ {{else}}
<form action="/download" method="POST" class="inline">
+ {{end}}
<div class="docs">
<table>
<tr>
@@ -39,7 +47,11 @@
<br/>
<input type="submit" value="Télécharger les fichiers sélectionnés">
</form>
+ {{if ne .UserImpersonation ""}}
+ <form action="/download?user={{.UserImpersonation}}" method="GET" class="inlineblk">
+ {{else}}
<form action="/download" method="GET" class="inlineblk">
+ {{end}}
<input type="submit" value="Télécharger tous les fichiers">
</form>
{{end}}