feat(api): add access control and binding endpoints

Add endpoints for master and key access management to configure default
and allowed namespaces, including propagation options.
Implement GET and DELETE operations for individual bindings.
Update sync service to persist bindings snapshots even when no upstreams
are available.
This commit is contained in:
zenfun
2025-12-17 01:08:01 +08:00
parent 16fceec8e7
commit 6d8a12df34
4 changed files with 350 additions and 5 deletions

View File

@@ -157,3 +157,68 @@ func (h *Handler) UpdateBinding(c *gin.Context) {
c.JSON(http.StatusOK, existing)
}
// GetBinding godoc
// @Summary Get a binding
// @Description Get a binding by id
// @Tags admin
// @Produce json
// @Security AdminAuth
// @Param id path int true "Binding ID"
// @Success 200 {object} model.Binding
// @Failure 400 {object} gin.H
// @Failure 404 {object} gin.H
// @Failure 500 {object} gin.H
// @Router /admin/bindings/{id} [get]
func (h *Handler) GetBinding(c *gin.Context) {
idParam := c.Param("id")
id, err := strconv.Atoi(idParam)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return
}
var existing model.Binding
if err := h.db.First(&existing, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "binding not found"})
return
}
c.JSON(http.StatusOK, existing)
}
// DeleteBinding godoc
// @Summary Delete a binding
// @Description Delete a binding by id and rebuild bindings snapshot
// @Tags admin
// @Produce json
// @Security AdminAuth
// @Param id path int true "Binding ID"
// @Success 200 {object} gin.H
// @Failure 400 {object} gin.H
// @Failure 404 {object} gin.H
// @Failure 500 {object} gin.H
// @Router /admin/bindings/{id} [delete]
func (h *Handler) DeleteBinding(c *gin.Context) {
idParam := c.Param("id")
id, err := strconv.Atoi(idParam)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return
}
var existing model.Binding
if err := h.db.First(&existing, id).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "binding not found"})
return
}
if err := h.db.Delete(&existing).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to delete binding", "details": err.Error()})
return
}
if err := h.sync.SyncBindings(h.db); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to sync bindings", "details": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "deleted"})
}