Files
yovision/Sense/server/app/sense/device/http.go
T

125 lines
4.2 KiB
Go

package device
import (
"net/http"
"strconv"
"yovision.local/sense/app/sense/identity"
"yovision.local/sense/internal/platform"
)
type Module struct{ service *Service }
func NewModule(service *Service) *Module { return &Module{service: service} }
func (m *Module) Register(app *platform.App) {
activeService.Store(m.service)
app.Handle("GET /api/v1/devices", identity.Require(identity.PermissionDeviceRead, http.HandlerFunc(m.list)))
app.Handle("POST /api/v1/devices", identity.Require(identity.PermissionDeviceWrite, http.HandlerFunc(m.create)))
app.Handle("GET /api/v1/devices/{id}", identity.Require(identity.PermissionDeviceRead, http.HandlerFunc(m.get)))
app.Handle("PATCH /api/v1/devices/{id}", identity.Require(identity.PermissionDeviceWrite, http.HandlerFunc(m.update)))
app.Handle("POST /api/v1/devices/{id}/credentials", identity.Require(identity.PermissionDeviceWrite, http.HandlerFunc(m.credential)))
app.Handle("POST /api/v1/devices/{id}/disable", identity.Require(identity.PermissionDeviceWrite, http.HandlerFunc(m.disable)))
}
func (m *Module) list(w http.ResponseWriter, r *http.Request) {
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
size, _ := strconv.Atoi(r.URL.Query().Get("page_size"))
result, err := m.service.List(r.Context(), ListFilter{Keyword: r.URL.Query().Get("keyword"), Page: page, PageSize: size})
if err != nil {
platform.WriteError(w, err)
return
}
platform.WriteJSON(w, http.StatusOK, result)
}
func (m *Module) get(w http.ResponseWriter, r *http.Request) {
item, err := m.service.Get(r.Context(), r.PathValue("id"))
if err != nil {
writeDeviceError(w, err)
return
}
platform.WriteJSON(w, http.StatusOK, item)
}
func (m *Module) create(w http.ResponseWriter, r *http.Request) {
var req struct {
Name string `json:"name"`
Location string `json:"location"`
Modality string `json:"modality"`
Capabilities []string `json:"capabilities"`
}
if err := platform.DecodeJSON(r, &req); err != nil {
platform.WriteError(w, err)
return
}
actor, _ := identity.PrincipalFromContext(r.Context())
item, err := m.service.Create(r.Context(), actor, req.Name, req.Location, req.Modality, req.Capabilities)
if err != nil {
writeDeviceError(w, err)
return
}
platform.WriteJSON(w, http.StatusCreated, item)
}
func (m *Module) update(w http.ResponseWriter, r *http.Request) {
var req struct {
Name string `json:"name"`
Location string `json:"location"`
Capabilities []string `json:"capabilities"`
Version int64 `json:"version"`
}
if err := platform.DecodeJSON(r, &req); err != nil {
platform.WriteError(w, err)
return
}
actor, _ := identity.PrincipalFromContext(r.Context())
item, err := m.service.Update(r.Context(), actor, r.PathValue("id"), req.Name, req.Location, req.Capabilities, req.Version)
if err != nil {
writeDeviceError(w, err)
return
}
platform.WriteJSON(w, http.StatusOK, item)
}
func (m *Module) credential(w http.ResponseWriter, r *http.Request) {
var req struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := platform.DecodeJSON(r, &req); err != nil {
platform.WriteError(w, err)
return
}
actor, _ := identity.PrincipalFromContext(r.Context())
item, err := m.service.SetCredential(r.Context(), actor, r.PathValue("id"), req.Username, req.Password)
if err != nil {
writeDeviceError(w, err)
return
}
platform.WriteJSON(w, http.StatusOK, item)
}
func (m *Module) disable(w http.ResponseWriter, r *http.Request) {
var req struct {
Version int64 `json:"version"`
}
if err := platform.DecodeJSON(r, &req); err != nil {
platform.WriteError(w, err)
return
}
actor, _ := identity.PrincipalFromContext(r.Context())
item, err := m.service.Disable(r.Context(), actor, r.PathValue("id"), req.Version)
if err != nil {
writeDeviceError(w, err)
return
}
platform.WriteJSON(w, http.StatusOK, item)
}
func writeDeviceError(w http.ResponseWriter, err error) {
status := http.StatusBadRequest
code := "device_invalid"
if err == ErrNotFound {
status = http.StatusNotFound
code = "device_not_found"
}
if err == ErrConflict {
status = http.StatusConflict
code = "version_conflict"
}
platform.WriteError(w, &platform.APIError{Status: status, Code: code, Message: err.Error()})
}