aboutsummaryrefslogtreecommitdiff
path: root/main.go
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 /main.go
parente7a3649280d20d9b4f68572721684a01049ec40f (diff)
downloaddocspace-f416775268085c7fb7f90cf54ea2149267b960e6.tar.gz
Add user impersonation support for admins
Diffstat (limited to 'main.go')
-rw-r--r--main.go53
1 files changed, 42 insertions, 11 deletions
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)
}