diff options
| author | haturatu <taro@eyes4you.org> | 2025-10-12 15:01:34 +0900 |
|---|---|---|
| committer | haturatu <taro@eyes4you.org> | 2025-10-12 15:01:34 +0900 |
| commit | 10c90d8654b94916bf0a4ffb8263e512a8e6be04 (patch) | |
| tree | dd109fb357abb40f943a7818fedc659e69ee5d11 /handlers/admin.go | |
first commit
Diffstat (limited to 'handlers/admin.go')
| -rw-r--r-- | handlers/admin.go | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/handlers/admin.go b/handlers/admin.go new file mode 100644 index 0000000..d9fb310 --- /dev/null +++ b/handlers/admin.go @@ -0,0 +1,155 @@ +package handlers + +import ( + "auth-proxy/config" + "auth-proxy/logging" + "auth-proxy/models" + "auth-proxy/types" + "encoding/json" + "net/http" + "strconv" +) + +// AdminPageHandler serves the admin dashboard page. +func AdminPageHandler(w http.ResponseWriter, r *http.Request) { + // Fetch all users to render on the page + users, err := models.GetAllUsers() + if err != nil { + logging.AppLog.Error("Failed to retrieve users for admin page", "error", err) + http.Error(w, "Could not load user data.", http.StatusInternalServerError) + return + } + + data := map[string]interface{}{ + "Paths": config.Paths, + "Users": users, + } + templates.ExecuteTemplate(w, "admin.html", data) +} + +// GetUsersHandler returns a list of all users. +func GetUsersHandler(w http.ResponseWriter, r *http.Request) { + ip := logging.GetClientIP(r) + users, err := models.GetAllUsers() + if err != nil { + logging.AppLog.Error("Failed to retrieve users", "error", err, "ip", ip) + http.Error(w, "Failed to retrieve users", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(users) +} + +// UpdateUserRoleHandler updates a user's role. +func UpdateUserRoleHandler(w http.ResponseWriter, r *http.Request) { + ip := logging.GetClientIP(r) + // Get admin user from context + adminUser, ok := r.Context().Value(types.SessionDataContextKey).(*models.User) + if !ok || adminUser == nil { + logging.AppLog.Error("Failed to get user from context for admin action", "ip", ip) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + adminUsername := adminUser.Username + + id, err := strconv.ParseInt(r.URL.Path[len(config.Paths.AdminUsersAPI+"/"):len(r.URL.Path)-len("/role")], 10, 64) + if err != nil { + logging.AppLog.Warn("Invalid user ID in request", "path", r.URL.Path, "ip", ip) + http.Error(w, "Invalid user ID", http.StatusBadRequest) + return + } + + var req struct { + Role string `json:"role"` + } + + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + logging.AppLog.Warn("Invalid request body for role update", "error", err, "ip", ip) + http.Error(w, "Invalid request body", http.StatusBadRequest) + return + } + + if req.Role != "admin" && req.Role != "user" { + logging.AppLog.Warn("Invalid role provided for update", "role", req.Role, "ip", ip) + http.Error(w, "Invalid role", http.StatusBadRequest) + return + } + + if err := models.UpdateUserRole(id, req.Role); err != nil { + logging.AppLog.Error("Failed to update user role in database", "error", err, "target_user_id", id, "ip", ip) + http.Error(w, "Failed to update role", http.StatusInternalServerError) + return + } + + logging.SecurityLog.Info("ADMIN ACTION", "action", "update_role", "performed_by", adminUsername, "target_user_id", id, "new_role", req.Role, "ip", ip) + w.WriteHeader(http.StatusOK) +} + +// DeleteUserHandler deletes a user. +func DeleteUserHandler(w http.ResponseWriter, r *http.Request) { + ip := logging.GetClientIP(r) + // Get admin user from context + adminUser, ok := r.Context().Value(types.SessionDataContextKey).(*models.User) + if !ok || adminUser == nil { + logging.AppLog.Error("Failed to get user from context for admin action", "ip", ip) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + adminUsername := adminUser.Username + + id, err := strconv.ParseInt(r.URL.Path[len(config.Paths.AdminUsersAPI+"/"):], 10, 64) + if err != nil { + logging.AppLog.Warn("Invalid user ID in request", "path", r.URL.Path, "ip", ip) + http.Error(w, "Invalid user ID", http.StatusBadRequest) + return + } + + if err := models.DeleteUser(id); err != nil { + logging.AppLog.Error("Failed to delete user from database", "error", err, "target_user_id", id, "ip", ip) + http.Error(w, "Failed to delete user", http.StatusInternalServerError) + return + } + + logging.SecurityLog.Info("ADMIN ACTION", "action", "delete_user", "performed_by", adminUsername, "target_user_id", id, "ip", ip) + w.WriteHeader(http.StatusOK) +} + +// SetUserActiveStatusHandler updates a user's active status. +func SetUserActiveStatusHandler(w http.ResponseWriter, r *http.Request) { + ip := logging.GetClientIP(r) + // Get admin user from context + adminUser, ok := r.Context().Value(types.SessionDataContextKey).(*models.User) + if !ok || adminUser == nil { + logging.AppLog.Error("Failed to get user from context for admin action", "ip", ip) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + adminUsername := adminUser.Username + + id, err := strconv.ParseInt(r.URL.Path[len(config.Paths.AdminUsersAPI+"/"):len(r.URL.Path)-len("/status")], 10, 64) + if err != nil { + logging.AppLog.Warn("Invalid user ID in request", "path", r.URL.Path, "ip", ip) + http.Error(w, "Invalid user ID", http.StatusBadRequest) + return + } + + var req struct { + IsActive bool `json:"is_active"` + } + + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + logging.AppLog.Warn("Invalid request body for status update", "error", err, "ip", ip) + http.Error(w, "Invalid request body", http.StatusBadRequest) + return + } + + if err := models.SetUserActiveStatus(id, req.IsActive); err != nil { + logging.AppLog.Error("Failed to update user status in database", "error", err, "target_user_id", id, "ip", ip) + http.Error(w, "Failed to update status", http.StatusInternalServerError) + return + } + + logging.SecurityLog.Info("ADMIN ACTION", "action", "set_active_status", "performed_by", adminUsername, "target_user_id", id, "new_status", req.IsActive, "ip", ip) + w.WriteHeader(http.StatusOK) +}
\ No newline at end of file |
