diff --git a/.gitignore b/.gitignore index 6029a75..e806cf8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -users.db +*.db start *.log \ No newline at end of file diff --git a/data/device_database.go b/data/device_database.go index 070d093..51469b5 100644 --- a/data/device_database.go +++ b/data/device_database.go @@ -25,7 +25,7 @@ func (db *DeviceDatabase) Initialize() error { _, error = db.Connection.Exec(`CREATE TABLE IF NOT EXISTS devices ( id TEXT PRIMARY KEY, device_name TEXT UNIQUE, - description TEXT, + description TEXT )`) if error != nil { return fmt.Errorf("error creating devices table: %s", error) diff --git a/main/main.go b/main/main.go index c2f5987..ad3bbf9 100644 --- a/main/main.go +++ b/main/main.go @@ -30,12 +30,27 @@ func main() { } defer userDatabase.Close() + deviceDatabase := data.DeviceDatabase{} + deviceDatabase.SetDirectory(configuration.DatabaseDirectory) + err = deviceDatabase.Initialize() + if err != nil { + log.Error().Err(err).Msg("failed to initialize device database") + os.Exit(1) + } + defer deviceDatabase.Close() + userManager := management.UserManager{} err = userManager.Initialize(&userDatabase) if err != nil { log.Error().Err(err).Msg("failed to initialize user manager") } + deviceManager := management.DeviceManager{} + err = deviceManager.Initialize(&deviceDatabase) + if err != nil { + log.Error().Err(err).Msg("failed to initialize device manager") + } + webServer := server.WebServer{} webServer.SetWebAppDirectoryPath("www") webServer.SetPort(configuration.Port) @@ -50,6 +65,11 @@ func main() { userApiHandler.SetRouter(webServer.Router()) userApiHandler.Initialize(&authenticator) + deviceApiHandler := server.DeviceApiHandler{} + deviceApiHandler.SetDeviceManager(&deviceManager) + deviceApiHandler.SetRouter(webServer.Router()) + deviceApiHandler.Initialize(&authenticator) + var wg sync.WaitGroup wg.Add(1) go func() { diff --git a/management/device_manager.go b/management/device_manager.go new file mode 100644 index 0000000..98f6b23 --- /dev/null +++ b/management/device_manager.go @@ -0,0 +1,84 @@ +package management + +import ( + d "playback-device-server/data" +) + +type DeviceManager struct { + deviceDatabase *d.DeviceDatabase +} + +func (um *DeviceManager) Initialize(deviceDatabase *d.DeviceDatabase) error { + um.deviceDatabase = deviceDatabase + return nil +} + +func (um *DeviceManager) CreateDevice(device *d.PlaybackDevice) (string, error) { + id, error := um.deviceDatabase.CreateDevice(device.Name, device.Description) + if error != nil { + return "", error + } + return id, nil +} + +func (um *DeviceManager) DeviceIdExists(id string) (bool, error) { + exists, error := um.deviceDatabase.DeviceIdExists(id) + if error != nil { + return false, error + } + return exists, nil +} + +//func (um *DeviceManager) Register(code string) (string, error) { +// device, error := um.GetDeviceByCode(code) +// if error != nil { +// return "", error +// } +// +// expiryDate := time.Now().AddDate(0, 0, 30) +// token, error := um.deviceDatabase.CreateSession(device.ID, expiryDate) +// if error != nil { +// return "", error +// } +// +// return token, nil +//} + +func (um *DeviceManager) GetSession(sessionToken string) (*d.DeviceSession, error) { + session, error := um.deviceDatabase.GetSession(sessionToken) + if error != nil { + return nil, error + } + return session, nil +} + +func (um *DeviceManager) GetDeviceById(id string) (*d.PlaybackDevice, error) { + device, error := um.deviceDatabase.GetDeviceById(id) + if error != nil { + return nil, error + } + return device, nil +} + +func (um *DeviceManager) UpdateDevice(device *d.PlaybackDevice) error { + error := um.deviceDatabase.UpdateDevice(device) + return error +} + +func (um *DeviceManager) DeleteSession(token string) error { + error := um.deviceDatabase.DeleteSessionByToken(token) + if error != nil { + return error + } + return nil +} + +func (um *DeviceManager) GetDevices() (*[]d.PlaybackDevice, error) { + users, error := um.deviceDatabase.GetDevices() + return users, error +} + +func (um *DeviceManager) DeleteDevice(ID string) error { + error := um.deviceDatabase.DeleteDevice(ID) + return error +} diff --git a/server/device_api_handler.go b/server/device_api_handler.go new file mode 100644 index 0000000..878d835 --- /dev/null +++ b/server/device_api_handler.go @@ -0,0 +1,183 @@ +package server + +import ( + "fmt" + d "playback-device-server/data" + m "playback-device-server/management" + + "github.com/labstack/echo/v4" +) + +type DeviceApiHandler struct { + router *echo.Echo + deviceManager *m.DeviceManager +} + +func (r *DeviceApiHandler) Initialize(authenticator *Authenticator) { + r.router.Use(authenticator.Authenticate("/api/devices", []string{})) + usersApi := r.router.Group("/api/devices") + //usersApi.POST("/register", r.handleRegister) + //usersApi.POST("/deregister", r.handleDeregister) + usersApi.GET("/session/info", r.handleGetSessionInfo) + usersApi.PUT("/:id", r.handleUpdateConfig) + usersApi.GET("", r.handleGetDevices) + usersApi.POST("", r.handleCreateDevice) + usersApi.DELETE("/:id", r.handleDeleteDevice) +} + +//func (r DeviceApiHandler) handleRegister(context echo.Context) error { +// var registrationData struct { +// Code string `json:"code"` +// } +// +// var errorResponse struct { +// Error string `json:"error"` +// } +// +// error := context.Bind(®istrationData) +// +// if error != nil { +// log.Info().Msgf("failed to bind registration data: %s", error) +// errorResponse.Error = fmt.Sprintf("%s", error) +// context.JSON(400, errorResponse) +// return error +// } +// +// token, error := r.deviceManger.Register(registrationData.Code) +// +// if error != nil { +// log.Info().Msgf("failed to register: %s", error) +// errorResponse.Error = fmt.Sprintf("%s", error) +// context.JSON(400, errorResponse) +// return error +// } +// +// thirdyDays := 30 * 24 * 60 * 60 +// +// cookie := &http.Cookie{ +// Name: "token", +// Value: token, +// Path: "/", +// HttpOnly: true, +// MaxAge: thirdyDays, +// } +// +// context.SetCookie(cookie) +// +// return context.JSON(200, "") +//} + +//func (r UsersApiHandler) handleDeregister(context echo.Context) error { +// r.removeTokenCookie(&context) +// context.JSON(200, "") +// +// authContext := context.(AuthContext) +// +// session := authContext.Session +// r.userManager.DeleteSession(session.Token) +// +// return nil +//} + +func (r DeviceApiHandler) handleGetSessionInfo(context echo.Context) error { + //authContext := context.(AuthContext) + //user := authContext.User + + response := struct { + IntegrationID string `json:"integration_id"` + IntegrationName string `json:"integration_name"` + DeviceID string `json:"device_id"` + DeviceName string `json:"device_name"` + }{ + IntegrationID: "", + IntegrationName: "", + DeviceID: "", + DeviceName: "", + } + + return context.JSON(200, response) +} + +func (r DeviceApiHandler) handleGetDevices(context echo.Context) error { + users, error := r.deviceManager.GetDevices() + if error != nil { + SendError(500, context, fmt.Sprintf("failed to get device list: %s", error)) + } + + return context.JSON(200, users) +} + +func (r DeviceApiHandler) handleCreateDevice(context echo.Context) error { + var newDevice d.PlaybackDevice + error := context.Bind(&newDevice) + + if error != nil { + SendError(500, context, fmt.Sprintf("Failed to create playback device: %s", error)) + return error + } + + id, error := r.deviceManager.CreateDevice(&newDevice) + + if error != nil { + SendError(500, context, fmt.Sprintf("Failed to create playback device: %s", error)) + return error + } + + newDevice.ID = id + + return context.JSON(200, newDevice) +} + +func (r DeviceApiHandler) handleDeleteDevice(context echo.Context) error { + id := context.Param("id") + + exists, error := r.deviceManager.DeviceIdExists(id) + + if error != nil { + SendError(500, context, fmt.Sprintf("Failed to delete playbac device: %s", error)) + return error + } + + if !exists { + SendError(404, context, fmt.Sprintf("Failed to delete playback device: Could not find device id %s", id)) + return fmt.Errorf("not found") + } + + error = r.deviceManager.DeleteDevice(id) + if error != nil { + SendError(500, context, fmt.Sprintf("Failed to delete playback device: %s", error)) + return error + } + + return context.JSON(200, "") +} + +func (r *DeviceApiHandler) handleUpdateConfig(context echo.Context) error { + id := context.Param("id") + + var newDevice d.PlaybackDevice + error := context.Bind(&newDevice) + + if error != nil { + SendError(500, context, fmt.Sprintf("Failed to update device config: %s", error)) + return error + } + + newDevice.ID = id + error = r.deviceManager.UpdateDevice(&newDevice) + + if error != nil { + SendError(500, context, fmt.Sprintf("Failed to update device config: %s", error)) + return error + } + + return context.JSON(200, newDevice) +} + +func (r *DeviceApiHandler) SetRouter(router *echo.Echo) { + r.router = router +} + +func (r *DeviceApiHandler) SetDeviceManager(deviceManager *m.DeviceManager) { + r.deviceManager = deviceManager +}