package server import ( "net/http" "git.haelnorr.com/h/golib/hws" "git.haelnorr.com/h/golib/hwsauth" "github.com/pkg/errors" "github.com/uptrace/bun" "git.haelnorr.com/h/oslstats/internal/config" "git.haelnorr.com/h/oslstats/internal/db" "git.haelnorr.com/h/oslstats/internal/discord" "git.haelnorr.com/h/oslstats/internal/handlers" "git.haelnorr.com/h/oslstats/internal/permissions" "git.haelnorr.com/h/oslstats/internal/rbac" "git.haelnorr.com/h/oslstats/internal/store" "git.haelnorr.com/h/oslstats/pkg/slapshotapi" ) func addRoutes( s *hws.Server, staticFS *http.FileSystem, cfg *config.Config, conn *db.DB, auth *hwsauth.Authenticator[*db.User, bun.Tx], store *store.Store, discordAPI *discord.APIClient, slapAPI *slapshotapi.SlapAPI, perms *rbac.Checker, ) error { // Create the routes baseRoutes := []hws.Route{ { Path: "/static/", Method: hws.MethodGET, Handler: http.StripPrefix("/static/", handlers.StaticFS(staticFS, s)), }, { Path: "/", Method: hws.MethodGET, Handler: handlers.Index(s), }, } authRoutes := []hws.Route{ { Path: "/login", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: auth.LogoutReq(handlers.Login(s, conn, cfg, store, discordAPI)), }, { Path: "/auth/callback", Method: hws.MethodGET, Handler: auth.LogoutReq(handlers.Callback(s, auth, conn, cfg, store, discordAPI)), }, { Path: "/register", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: auth.LogoutReq(handlers.Register(s, auth, conn, slapAPI, cfg, store)), }, { Path: "/logout", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: auth.LoginReq(handlers.Logout(s, auth, conn, discordAPI)), }, } seasonRoutes := []hws.Route{ { Path: "/seasons", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: handlers.SeasonsPage(s, conn), }, { Path: "/seasons/new", Method: hws.MethodGET, Handler: perms.RequirePermission(s, permissions.SeasonsCreate)(handlers.NewSeason(s)), }, { Path: "/seasons/new", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.SeasonsCreate)(handlers.NewSeasonSubmit(s, conn)), }, { Path: "/seasons/{season_short_name}", Method: hws.MethodGET, Handler: handlers.SeasonPage(s, conn), }, { Path: "/seasons/{season_short_name}/edit", Method: hws.MethodGET, Handler: perms.RequirePermission(s, permissions.SeasonsUpdate)(handlers.SeasonEditPage(s, conn)), }, { Path: "/seasons/{season_short_name}/edit", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.SeasonsUpdate)(handlers.SeasonEditSubmit(s, conn)), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}", Method: hws.MethodGET, Handler: handlers.SeasonLeaguePage(s, conn), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/table", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: handlers.SeasonLeagueTablePage(s, conn), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/fixtures", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: handlers.SeasonLeagueFixturesPage(s, conn), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/teams", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: handlers.SeasonLeagueTeamsPage(s, conn), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/stats", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: handlers.SeasonLeagueStatsPage(s, conn), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/finals", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: handlers.SeasonLeagueFinalsPage(s, conn), }, { Path: "/seasons/{season_short_name}/add-league/{league_short_name}", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.SeasonsAddLeague)(handlers.SeasonAddLeague(s, conn)), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}", Method: hws.MethodDELETE, Handler: perms.RequirePermission(s, permissions.SeasonsRemoveLeague)(handlers.SeasonRemoveLeague(s, conn)), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/teams/add", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.TeamsAddToLeague)(handlers.SeasonLeagueAddTeam(s, conn)), }, } leagueRoutes := []hws.Route{ { Path: "/leagues", Method: hws.MethodGET, Handler: handlers.LeaguesList(s, conn), }, { Path: "/leagues/new", Method: hws.MethodGET, Handler: perms.RequirePermission(s, permissions.LeaguesCreate)(handlers.NewLeague(s)), }, { Path: "/leagues/new", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.LeaguesCreate)(handlers.NewLeagueSubmit(s, conn)), }, } fixturesRoutes := []hws.Route{ { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/fixtures/manage", Method: hws.MethodGET, Handler: perms.RequirePermission(s, permissions.FixturesManage)(handlers.SeasonLeagueManageFixturesPage(s, conn)), }, { Path: "/fixtures/generate", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.FixturesCreate)(handlers.GenerateFixtures(s, conn)), }, { Path: "/fixtures/update-game-weeks", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.FixturesManage)(handlers.UpdateFixtures(s, conn)), }, { Path: "/seasons/{season_short_name}/leagues/{league_short_name}/fixtures", Method: hws.MethodDELETE, Handler: perms.RequirePermission(s, permissions.FixturesDelete)(handlers.SeasonLeagueDeleteFixtures(s, conn)), }, { Path: "/fixtures/{fixture_id}", Method: hws.MethodDELETE, Handler: perms.RequirePermission(s, permissions.FixturesDelete)(handlers.DeleteFixture(s, conn)), }, } teamRoutes := []hws.Route{ { Path: "/teams", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: handlers.TeamsPage(s, conn), }, { Path: "/teams/new", Method: hws.MethodGET, Handler: perms.RequirePermission(s, permissions.TeamsCreate)(handlers.NewTeamPage(s)), }, { Path: "/teams/new", Method: hws.MethodPOST, Handler: perms.RequirePermission(s, permissions.TeamsCreate)(handlers.NewTeamSubmit(s, conn)), }, } htmxRoutes := []hws.Route{ { Path: "/htmx/isusernameunique", Method: hws.MethodPOST, Handler: handlers.IsUnique(s, conn, (*db.User)(nil), "username"), }, { Path: "/htmx/isseasonnameunique", Method: hws.MethodPOST, Handler: handlers.IsUnique(s, conn, (*db.Season)(nil), "name"), }, { Path: "/htmx/isseasonshortnameunique", Method: hws.MethodPOST, Handler: handlers.IsUnique(s, conn, (*db.Season)(nil), "short_name"), }, { Path: "/htmx/isleaguenameunique", Method: hws.MethodPOST, Handler: handlers.IsUnique(s, conn, (*db.League)(nil), "name"), }, { Path: "/htmx/isleagueshortnameunique", Method: hws.MethodPOST, Handler: handlers.IsUnique(s, conn, (*db.League)(nil), "short_name"), }, { Path: "/htmx/isteamnameunique", Method: hws.MethodPOST, Handler: handlers.IsUnique(s, conn, (*db.Team)(nil), "name"), }, { Path: "/htmx/isteamshortnamesunique", Method: hws.MethodPOST, Handler: handlers.IsTeamShortNamesUnique(s, conn), }, } wsRoutes := []hws.Route{ { Path: "/ws/notifications", Method: hws.MethodGET, Handler: handlers.NotificationWS(s, cfg), }, } // Admin routes adminRoutes := []hws.Route{ { Path: "/notification-tester", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: perms.RequireAdmin(s)(handlers.NotifyTester(s)), }, // Full page routes (for direct navigation and refreshes) { Path: "/admin", Method: hws.MethodGET, Handler: perms.RequireAdmin(s)(handlers.AdminDashboard(s, conn)), }, { Path: "/admin/users", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: perms.RequireAdmin(s)(handlers.AdminUsersPage(s, conn)), }, { Path: "/admin/roles", Methods: []hws.Method{hws.MethodGET, hws.MethodPOST}, Handler: perms.RequireAdmin(s)(handlers.AdminRoles(s, conn)), }, { Path: "/admin/audit", Method: hws.MethodGET, Handler: perms.RequireAdmin(s)(handlers.AdminAuditLogsPage(s, conn)), }, { Path: "/admin/audit", Method: hws.MethodPOST, Handler: perms.RequireAdmin(s)(handlers.AdminAuditLogsList(s, conn)), }, // Role management routes { Path: "/admin/roles/create", Method: hws.MethodGET, Handler: perms.RequireAdmin(s)(handlers.AdminRoleCreateForm(s)), }, { Path: "/admin/roles/create", Method: hws.MethodPOST, Handler: perms.RequireAdmin(s)(handlers.AdminRoleCreate(s, conn)), }, { Path: "/admin/roles/{id}/manage", Method: hws.MethodGET, Handler: perms.RequireAdmin(s)(handlers.AdminRoleManage(s, conn)), }, { Path: "/admin/roles/{id}", Method: hws.MethodDELETE, Handler: perms.RequireAdmin(s)(handlers.AdminRoleDelete(s, conn)), }, { Path: "/admin/roles/{id}/delete-confirm", Method: hws.MethodGET, Handler: perms.RequireAdmin(s)(handlers.AdminRoleDeleteConfirm(s, conn)), }, { Path: "/admin/roles/{id}/permissions", Method: hws.MethodGET, Handler: perms.RequireAdmin(s)(handlers.AdminRolePermissionsModal(s, conn)), }, { Path: "/admin/roles/{id}/permissions", Method: hws.MethodPOST, Handler: perms.RequireAdmin(s)(handlers.AdminRolePermissionsUpdate(s, conn)), }, { Path: "/admin/roles/{id}/preview-start", Method: hws.MethodPOST, Handler: perms.RequireAdmin(s)(handlers.AdminPreviewRoleStart(s, conn, cfg.HWSAuth.SSL)), }, { Path: "/admin/roles/preview-stop", Method: hws.MethodPOST, Handler: perms.RequireActualAdmin(s)(handlers.AdminPreviewRoleStop(s)), }, { Path: "/admin/audit/filter", Method: hws.MethodPOST, Handler: perms.RequireAdmin(s)(handlers.AdminAuditLogsFilter(s, conn)), }, { Path: "/admin/audit/{id}", Method: hws.MethodGET, Handler: perms.RequireAdmin(s)(handlers.AdminAuditLogDetail(s, conn)), }, } routes := append(baseRoutes, htmxRoutes...) routes = append(routes, wsRoutes...) routes = append(routes, authRoutes...) routes = append(routes, adminRoutes...) routes = append(routes, seasonRoutes...) routes = append(routes, leagueRoutes...) routes = append(routes, fixturesRoutes...) routes = append(routes, teamRoutes...) // Register the routes with the server err := s.AddRoutes(routes...) if err != nil { return errors.Wrap(err, "server.AddRoutes") } return nil }