Initialize AutoLibrary website with Gitea deployment

This commit is contained in:
KenanZhu committed 2026-11-04 09:59:06 +08:00
commit 18216953e7
101 files changed
+12581

No files matched your search

+172
View File
@@ -0,0 +1,172 @@
package backend
import (
"context"
"errors"
"log"
"net"
"net/http"
"path/filepath"
"time"
"autolibrary.top/webserver/backend/database/bulletins_database"
"autolibrary.top/webserver/backend/database/themes_database"
"autolibrary.top/webserver/backend/database/versions_database"
"autolibrary.top/webserver/backend/handlers/bulletins_handler"
"autolibrary.top/webserver/backend/handlers/errors_handler"
"autolibrary.top/webserver/backend/handlers/health_handler"
"autolibrary.top/webserver/backend/handlers/themes_handler"
"autolibrary.top/webserver/backend/handlers/versions_handler"
"autolibrary.top/webserver/backend/middlewares/auth_middleware"
"autolibrary.top/webserver/backend/middlewares/casdoor_middleware"
"autolibrary.top/webserver/backend/services/theme_files"
"autolibrary.top/webserver/backend/services/users_service"
"autolibrary.top/webserver/config"
"autolibrary.top/webserver/utils"
"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
"github.com/gin-gonic/gin"
)
// StartBackend : initializes the backend server.
func StartBackend() error { return StartBackendContext(context.Background()) }
func StartBackendContext(ctx context.Context) error {
defer EndBackend()
cfg := config.GetConfig()
gin.SetMode(gin.ReleaseMode)
err := versions_database.InitDB(cfg.Backend.Database.Versions.Path)
if err != nil {
log.Printf("[E] versions database initialization failed: %v", err)
return err
}
err = bulletins_database.InitDB(cfg.Backend.Database.Bulletins.Path)
if err != nil {
log.Printf("[E] bulletins database initialization failed: %v", err)
return err
}
err = themes_database.InitDB(cfg.Backend.Database.Themes.Path)
if err != nil {
log.Printf("[E] themes database initialization failed: %v", err)
return err
}
files, err := theme_files.NewStore(cfg.Backend.Database.ThemesFiles.Path)
if err != nil {
return err
}
users := users_service.New(cfg.Backend.Casdoor.Endpoint != "" && cfg.Backend.Casdoor.ClientID != "")
themes := themes_handler.New(themes_database.DB, cfg, files, users)
// Pre-initialize Casdoor SDK and user display-name cache
if cfg.Backend.Casdoor.Endpoint != "" && cfg.Backend.Casdoor.ClientID != "" {
casdoorsdk.InitConfig(
cfg.Backend.Casdoor.Endpoint,
cfg.Backend.Casdoor.ClientID,
cfg.Backend.Casdoor.ClientSecret,
cfg.Backend.Casdoor.Certificate,
cfg.Backend.Casdoor.Organization,
cfg.Backend.Casdoor.Application,
)
casdoorsdk.SetHttpClient(&http.Client{Timeout: 15 * time.Second})
}
r := gin.New()
r.MaxMultipartMemory = 8 << 20
r.Use(func(c *gin.Context) { c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 16<<20); c.Next() })
r.Use(gin.Recovery())
r.Use(func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-API-Key, X-Requested-With")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
})
templateDir := filepath.Join(utils.GetRootPath(), "backend", "templates")
templateFiles := []string{
filepath.Join(templateDir, "404.html"),
}
r.LoadHTMLFiles(templateFiles...)
public := r.Group("/")
{
public.GET("/health", health_handler.GetHealth)
public.GET("/download/latest", versions_handler.GetLatestDownload)
public.GET("/download/versions", versions_handler.GetDownloadVersions)
public.GET("/download/versions/:id", versions_handler.GetDownloadVersionByID)
public.GET("/bulletins", bulletins_handler.GetBulletins)
public.GET("/bulletins/:id", bulletins_handler.GetBulletinByID)
}
// Marketplace public routes
mp := r.Group("/marketplace")
{
mp.GET("/auth/config", themes.GetAuthConfig)
mp.GET("/auth/captcha", themes.GetCaptcha)
mp.POST("/auth/login", themes.LoginProxy)
mp.POST("/auth/signup", themes.SignupProxy)
mp.GET("/themes/featured", themes.GetFeaturedThemes)
mp.GET("/themes/preview/:filename", themes.ServePreview)
mp.GET("/themes", themes.GetThemes)
mp.GET("/themes/:id", themes.GetThemeByID)
mp.GET("/themes/:id/download", themes.DownloadTheme)
}
// Marketplace admin routes (API key)
mpAdmin := r.Group("/marketplace")
mpAdmin.Use(auth_middleware.APIKeyAuth())
{
mpAdmin.PUT("/admin/themes/:id/review", themes.ReviewTheme)
mpAdmin.GET("/admin/themes/pending", themes.GetPendingThemes)
}
// Marketplace user routes (Casdoor JWT)
mpUser := r.Group("/marketplace")
mpUser.Use(casdoor_middleware.CasdoorAuth())
{
mpUser.POST("/themes", themes.PostTheme)
mpUser.PUT("/themes/:id", themes.PutThemeByID)
mpUser.DELETE("/themes/:id", themes.DeleteThemeByID)
mpUser.GET("/user/check-theme-name", themes.CheckThemeName)
mpUser.POST("/themes/:id/preview", themes.UploadPreview)
mpUser.POST("/themes/:id/file", themes.ReplaceThemeFile)
mpUser.GET("/user/themes", themes.GetUserThemes)
mpUser.GET("/user/downloads", themes.GetUserDownloads)
mpUser.GET("/user/role", themes.GetUserRole)
}
// Marketplace admin routes (Casdoor JWT + admin check)
mpAdminUser := r.Group("/marketplace")
mpAdminUser.Use(casdoor_middleware.CasdoorAdminAuth())
{
mpAdminUser.GET("/admin/pending", themes.GetPendingThemes)
mpAdminUser.PUT("/admin/review/:id", themes.ReviewTheme)
mpAdminUser.GET("/admin/download/:id", themes.AdminDownloadTheme)
}
protected := r.Group("/")
protected.Use(auth_middleware.APIKeyAuth())
{
protected.POST("/download/versions", versions_handler.PostDownloadVersion)
protected.PUT("/download/versions/:id", versions_handler.PutDownloadVersionByID)
protected.DELETE("/download/versions/:id", versions_handler.DeleteDownloadVersionByID)
protected.POST("/bulletins", bulletins_handler.PostBulletin)
protected.PUT("/bulletins/:id", bulletins_handler.PutBulletinByID)
protected.DELETE("/bulletins/:id", bulletins_handler.DeleteBulletinByID)
}
r.NoRoute(errors_handler.GetNotFoundError)
backend_address := net.JoinHostPort(cfg.Backend.Host, cfg.Backend.Port)
log.Printf("[I] backend server is running on: http://%s", backend_address)
return utils.ServeHTTP(ctx, backend_address, r)
}
// EndBackend : closes the database connection.
func EndBackend() error {
return errors.Join(versions_database.CloseDB(), bulletins_database.CloseDB(), themes_database.CloseDB())
}