Add Blossom admin UI for viewing all users' storage (v0.36.21)
Some checks failed
Go / build-and-release (push) Has been cancelled
Some checks failed
Go / build-and-release (push) Has been cancelled
- Add ListAllUserStats() storage method to aggregate user blob stats - Add handleAdminListUsers() handler for admin endpoint - Add /blossom/admin/users route requiring admin ACL - Add Admin button to Blossom UI for admin/owner roles - Add admin view showing all users with file counts and sizes - Add user detail view to browse individual user's files - Fetch user profiles (avatar, name) for admin list display Files modified: - pkg/blossom/storage.go: Add UserBlobStats struct and ListAllUserStats() - pkg/blossom/handlers.go: Add handleAdminListUsers() handler - pkg/blossom/server.go: Add admin/users route - app/web/src/BlossomView.svelte: Add admin view state, UI, and styles 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -474,6 +474,42 @@ func (s *Server) handleListBlobs(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// handleAdminListUsers handles GET /admin/users requests (admin only)
|
||||
func (s *Server) handleAdminListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
// Authorization required
|
||||
authEv, err := ValidateAuthEvent(r, "admin", nil)
|
||||
if err != nil {
|
||||
s.setErrorResponse(w, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
if authEv == nil {
|
||||
s.setErrorResponse(w, http.StatusUnauthorized, "authorization required")
|
||||
return
|
||||
}
|
||||
|
||||
// Check admin ACL
|
||||
remoteAddr := s.getRemoteAddr(r)
|
||||
if !s.checkACL(authEv.Pubkey, remoteAddr, "admin") {
|
||||
s.setErrorResponse(w, http.StatusForbidden, "admin access required")
|
||||
return
|
||||
}
|
||||
|
||||
// Get all user stats
|
||||
stats, err := s.storage.ListAllUserStats()
|
||||
if err != nil {
|
||||
log.E.F("error listing user stats: %v", err)
|
||||
s.setErrorResponse(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
|
||||
// Return JSON
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if err = json.NewEncoder(w).Encode(stats); err != nil {
|
||||
log.E.F("error encoding response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// handleDeleteBlob handles DELETE /<sha256> requests (BUD-02)
|
||||
func (s *Server) handleDeleteBlob(w http.ResponseWriter, r *http.Request) {
|
||||
path := strings.TrimPrefix(r.URL.Path, "/")
|
||||
|
||||
Reference in New Issue
Block a user