Initial project snapshot
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"github.com/example/remote-access-platform/backend/internal/platform/httpx"
|
||||
"github.com/example/remote-access-platform/backend/internal/platform/module"
|
||||
)
|
||||
|
||||
type Module struct {
|
||||
service *Service
|
||||
}
|
||||
|
||||
func NewModule(deps module.Dependencies, service *Service) *Module {
|
||||
return &Module{service: service}
|
||||
}
|
||||
|
||||
func (m *Module) Name() string {
|
||||
return "auth"
|
||||
}
|
||||
|
||||
func (m *Module) RegisterRoutes(router chi.Router) {
|
||||
router.Route("/installation", func(r chi.Router) {
|
||||
r.Get("/status", m.handleInstallationStatus)
|
||||
r.Post("/bootstrap-owner", m.handleBootstrapOwner)
|
||||
})
|
||||
router.Route("/auth", func(r chi.Router) {
|
||||
r.Post("/login", m.handleLogin)
|
||||
r.Post("/refresh", m.handleRefresh)
|
||||
r.Post("/sessions/revoke", m.handleRevokeAuthSession)
|
||||
r.Get("/devices", m.handleTrustedDevices)
|
||||
r.Post("/devices/{deviceID}/revoke", m.handleRevokeTrustedDevice)
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Module) handleInstallationStatus(w http.ResponseWriter, r *http.Request) {
|
||||
status, err := m.service.InstallationStatus(r.Context())
|
||||
if err != nil {
|
||||
statusCode, message := m.service.MapError(err)
|
||||
httpx.WriteError(w, statusCode, message)
|
||||
return
|
||||
}
|
||||
httpx.WriteJSON(w, http.StatusOK, map[string]any{"installation": status})
|
||||
}
|
||||
|
||||
func (m *Module) handleBootstrapOwner(w http.ResponseWriter, r *http.Request) {
|
||||
var cmd BootstrapOwnerCommand
|
||||
if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil {
|
||||
httpx.WriteError(w, http.StatusBadRequest, "invalid installation bootstrap payload")
|
||||
return
|
||||
}
|
||||
result, err := m.service.BootstrapOwner(r.Context(), cmd)
|
||||
if err != nil {
|
||||
status, message := m.service.MapError(err)
|
||||
httpx.WriteError(w, status, message)
|
||||
return
|
||||
}
|
||||
httpx.WriteJSON(w, http.StatusCreated, result)
|
||||
}
|
||||
|
||||
func (m *Module) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
var cmd LoginCommand
|
||||
if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil {
|
||||
httpx.WriteError(w, http.StatusBadRequest, "invalid login payload")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := m.service.Login(r.Context(), cmd)
|
||||
if err != nil {
|
||||
status, message := m.service.MapError(err)
|
||||
httpx.WriteError(w, status, message)
|
||||
return
|
||||
}
|
||||
|
||||
httpx.WriteJSON(w, http.StatusOK, result)
|
||||
}
|
||||
|
||||
func (m *Module) handleRefresh(w http.ResponseWriter, r *http.Request) {
|
||||
var cmd RefreshCommand
|
||||
if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil {
|
||||
httpx.WriteError(w, http.StatusBadRequest, "invalid refresh payload")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := m.service.Refresh(r.Context(), cmd)
|
||||
if err != nil {
|
||||
status, message := m.service.MapError(err)
|
||||
httpx.WriteError(w, status, message)
|
||||
return
|
||||
}
|
||||
|
||||
httpx.WriteJSON(w, http.StatusOK, result)
|
||||
}
|
||||
|
||||
func (m *Module) handleRevokeAuthSession(w http.ResponseWriter, r *http.Request) {
|
||||
var cmd RevokeAuthSessionCommand
|
||||
if err := json.NewDecoder(r.Body).Decode(&cmd); err != nil {
|
||||
httpx.WriteError(w, http.StatusBadRequest, "invalid auth session revoke payload")
|
||||
return
|
||||
}
|
||||
|
||||
if err := m.service.RevokeAuthSession(r.Context(), cmd); err != nil {
|
||||
status, message := m.service.MapError(err)
|
||||
httpx.WriteError(w, status, message)
|
||||
return
|
||||
}
|
||||
|
||||
httpx.WriteJSON(w, http.StatusAccepted, map[string]any{
|
||||
"status": "revoked",
|
||||
"message": httpx.NewMessage(
|
||||
"auth.session.revoked",
|
||||
"status.auth.session.revoked",
|
||||
"Auth session revoked.",
|
||||
nil,
|
||||
"",
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Module) handleTrustedDevices(w http.ResponseWriter, r *http.Request) {
|
||||
userID := r.URL.Query().Get("user_id")
|
||||
if userID == "" {
|
||||
httpx.WriteError(w, http.StatusBadRequest, "user_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
devices, err := m.service.ListTrustedDevices(r.Context(), userID)
|
||||
if err != nil {
|
||||
status, message := m.service.MapError(err)
|
||||
httpx.WriteError(w, status, message)
|
||||
return
|
||||
}
|
||||
|
||||
httpx.WriteJSON(w, http.StatusOK, map[string]any{
|
||||
"devices": devices,
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Module) handleRevokeTrustedDevice(w http.ResponseWriter, r *http.Request) {
|
||||
var payload struct {
|
||||
UserID string `json:"user_id"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
||||
httpx.WriteError(w, http.StatusBadRequest, "invalid device revoke payload")
|
||||
return
|
||||
}
|
||||
|
||||
err := m.service.RevokeTrustedDevice(r.Context(), RevokeDeviceCommand{
|
||||
UserID: payload.UserID,
|
||||
DeviceID: chi.URLParam(r, "deviceID"),
|
||||
Reason: payload.Reason,
|
||||
})
|
||||
if err != nil {
|
||||
status, message := m.service.MapError(err)
|
||||
httpx.WriteError(w, status, message)
|
||||
return
|
||||
}
|
||||
|
||||
httpx.WriteJSON(w, http.StatusAccepted, map[string]any{
|
||||
"status": "revoked",
|
||||
"message": httpx.NewMessage(
|
||||
"auth.device.revoked",
|
||||
"status.auth.device.revoked",
|
||||
"Trusted device revoked.",
|
||||
nil,
|
||||
"",
|
||||
),
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user