forked from Nixius/authelia
65 lines
1.8 KiB
Go
65 lines
1.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
"regexp"
|
|
)
|
|
|
|
var validUsername = regexp.MustCompile(`^[a-z0-9][a-z0-9_-]*$`)
|
|
|
|
// handleDeleteUser fully deletes an account plus its customer stack and volumes.
|
|
// Requires ADMIN_SECRET env set and X-Admin-Secret header. POST /admin/delete-user?user=instance-slug
|
|
func (a *App) handleDeleteUser(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
if a.cfg.AdminSecret == "" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
secret := r.Header.Get("X-Admin-Secret")
|
|
if secret != a.cfg.AdminSecret {
|
|
http.Error(w, "forbidden", http.StatusForbidden)
|
|
return
|
|
}
|
|
slug := r.URL.Query().Get("user")
|
|
if slug == "" {
|
|
slug = r.FormValue("user")
|
|
}
|
|
if slug == "" {
|
|
http.Error(w, "user required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if !validUsername.MatchString(slug) {
|
|
http.Error(w, "invalid username", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
inst, err := a.accounts.DeleteAccountByInstanceSlug(r.Context(), slug)
|
|
if err != nil {
|
|
log.Printf("admin delete-user %s: account: %v", slug, err)
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if err := a.swarm.RemoveStackAndVolumes(inst.StackName); err != nil {
|
|
log.Printf("admin delete-user %s: stack/volumes: %v", slug, err)
|
|
// Account already deleted; report but don't fail.
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"status": "user deleted",
|
|
"warning": "stack/volumes: " + err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{"status": "deleted", "user": slug})
|
|
}
|