diff --git a/server/constants.go b/server/constants.go index 9120826..2edf419 100644 --- a/server/constants.go +++ b/server/constants.go @@ -6,6 +6,7 @@ const ( URIHardFail = "/hard-fail" URISoftFail = "/soft-fail" URIAppVersions = "/app-versions" + URIAppVersion = "/app-versions/:version" URIReinit = "/reinit" URIMapPack = "/mappack" URIHandshake = "/handshake" diff --git a/server/handling.go b/server/handling.go index eba61dc..e7015e5 100644 --- a/server/handling.go +++ b/server/handling.go @@ -115,6 +115,8 @@ func (s *Server) setupRouter() *gin.Engine { }) router.GET(URIAppVersions, s.handleGETAppVersions) router.POST(URIAppVersions, s.handlePOSTAppVersions) + router.GET(URIAppVersion, s.handleGETAppVersion) + router.DELETE(URIAppVersion, s.handleDELETEAppVersion) router.POST(URIReinit, s.handlePOSTReset) return router @@ -179,6 +181,44 @@ func (s *Server) handlePOSTAppVersions(gc *gin.Context) { gc.Status(http.StatusNoContent) } +func (s *Server) handleGETAppVersion(gc *gin.Context) { + version := gc.Param("version") + if version == "" { + badRequest(gc, fmt.Errorf("version not provided")) + return + } + + ver, err := s.getAppVersion(version) + if err != nil { + internalError(gc, err) + return + } + if ver == nil { + gc.Status(http.StatusNotFound) + return + } + gc.JSON(http.StatusOK, ver) +} + +func (s *Server) handleDELETEAppVersion(gc *gin.Context) { + version := gc.Param("version") + if version == "" { + badRequest(gc, fmt.Errorf("version not provided")) + return + } + + deleted, err := s.deleteAppVersion(version) + if err != nil { + internalError(gc, err) + return + } + if !deleted { + gc.Status(http.StatusNotFound) + return + } + gc.Status(http.StatusNoContent) +} + func (s *Server) handlePOSTReset(gc *gin.Context) { err := s.initDB(true) if err != nil { diff --git a/server/server.go b/server/server.go index 7534157..c9a4e94 100644 --- a/server/server.go +++ b/server/server.go @@ -434,6 +434,44 @@ func (s *Server) putAppVersion(versionInfo *models.AppVersionInfo) error { return nil } +func (s *Server) getAppVersion(version string) (*models.AppVersionInfo, error) { + conn := s.getDbConn() + defer s.dbpool.Put(conn) + + var v *models.AppVersionInfo + err := sqlitex.Exec(conn, "select version, address from app_versions where version = ?", func(stmt *sqlite.Stmt) error { + verStr := stmt.ColumnText(0) + ver, err := semver.NewVersion(verStr) + if err != nil { + return fmt.Errorf("failed to parse version string %s from db: %w", verStr, err) + } + addr := stmt.ColumnText(1) + v = &models.AppVersionInfo{ + Version: *ver, + Address: addr, + } + return nil + }, version) + if err != nil { + return nil, fmt.Errorf("failed to retrieve app version %s from db: %w", version, err) + } + + return v, nil +} + +func (s *Server) deleteAppVersion(version string) (bool, error) { + conn := s.getDbConn() + defer s.dbpool.Put(conn) + + err := sqlitex.Exec(conn, "delete from app_versions where version = ?", nil, version) + if err != nil { + return false, fmt.Errorf("failed to delete app version %s from db: %w", version, err) + } + n := conn.Changes() + + return n > 0, nil +} + func (s *Server) handshake(hc models.HandshakeChallenge) (models.UserID, error) { conn := s.getDbConn() defer s.dbpool.Put(conn)