package api import ( "fmt" "net/http" "github.com/owen/vibeproxy/internal/database" "github.com/owen/vibeproxy/internal/models" ) func (a *API) listAccessLists(w http.ResponseWriter, r *http.Request) { lists, err := database.ListAccessLists(a.db) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, lists) } func (a *API) getAccessList(w http.ResponseWriter, r *http.Request) { id, err := pathID(r) if err != nil { writeError(w, http.StatusBadRequest, "invalid id") return } l, err := database.GetAccessList(a.db, id) if err != nil { writeError(w, http.StatusNotFound, "access list not found") return } writeJSON(w, http.StatusOK, l) } func (a *API) createAccessList(w http.ResponseWriter, r *http.Request) { var l models.AccessList if !decodeJSON(w, r, &l) { return } if err := validateAccessList(&l); err != nil { writeError(w, http.StatusBadRequest, err.Error()) return } l.ID = 0 id, err := database.SaveAccessList(a.db, &l) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } a.reload(r) audit(a.db, r, "access_list_changed", l.Name, fmt.Sprintf("id=%d created", id)) writeJSON(w, http.StatusCreated, l) } func (a *API) updateAccessList(w http.ResponseWriter, r *http.Request) { id, err := pathID(r) if err != nil { writeError(w, http.StatusBadRequest, "invalid id") return } var l models.AccessList if !decodeJSON(w, r, &l) { return } l.ID = id if err := validateAccessList(&l); err != nil { writeError(w, http.StatusBadRequest, err.Error()) return } if _, err := database.SaveAccessList(a.db, &l); err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } a.reload(r) audit(a.db, r, "access_list_changed", l.Name, fmt.Sprintf("id=%d updated", id)) writeJSON(w, http.StatusOK, l) } func (a *API) deleteAccessList(w http.ResponseWriter, r *http.Request) { id, err := pathID(r) if err != nil { writeError(w, http.StatusBadRequest, "invalid id") return } if err := database.DeleteAccessList(a.db, id); err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } a.reload(r) audit(a.db, r, "access_list_changed", fmt.Sprintf("id=%d", id), "deleted") w.WriteHeader(http.StatusNoContent) } func validateAccessList(l *models.AccessList) error { if l.Name == "" { return fmt.Errorf("name is required") } for i, rule := range l.Rules { if rule.Action != models.AccessAllow && rule.Action != models.AccessDeny { return fmt.Errorf("rule %d: action must be allow or deny", i) } if rule.CIDR == "" { return fmt.Errorf("rule %d: CIDR is required", i) } } return nil }