155 lines
7.0 KiB
Go
155 lines
7.0 KiB
Go
package api
|
|
|
|
import (
|
|
domainArticle "RenewCMS/internal/domain/article"
|
|
domainImage "RenewCMS/internal/domain/image"
|
|
domainInvite "RenewCMS/internal/domain/invite"
|
|
domainMail "RenewCMS/internal/domain/mail"
|
|
domainUser "RenewCMS/internal/domain/user"
|
|
"RenewCMS/internal/infrastructure/config"
|
|
"RenewCMS/internal/infrastructure/hashing"
|
|
"RenewCMS/internal/infrastructure/mailer"
|
|
"RenewCMS/internal/infrastructure/persistence/models"
|
|
persistence "RenewCMS/internal/infrastructure/persistence/repositories"
|
|
"RenewCMS/internal/infrastructure/useCases"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/glebarez/sqlite"
|
|
"github.com/go-chi/jwtauth/v5"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type UseCases struct {
|
|
Token *jwtauth.JWTAuth
|
|
CreateArticleUseCase *useCases.CreateArticleUseCase
|
|
GetArticleUseCase *useCases.GetArticleUseCase
|
|
ListArticlesUseCase *useCases.ListArticlesUseCase
|
|
UpdateArticleUseCase *useCases.UpdateArticleUseCase
|
|
DeleteArticleUseCase *useCases.DeleteArticleUseCase
|
|
GetUserUseCase *useCases.GetUserUseCase
|
|
CreateUserUseCase *useCases.CreateUserUseCase
|
|
AuthenticateUserUseCase *useCases.AuthenticateUserUseCase
|
|
VerifyUserUseCase *useCases.VerifyUserUseCase
|
|
CancelRegistrationUseCase *useCases.CancelRegistrationUseCase
|
|
RequestPasswordResetUseCase *useCases.RequestPasswordResetUseCase
|
|
ResetPasswordUseCase *useCases.ResetPasswordUseCase
|
|
UpdateUserProfileUseCase *useCases.UpdateUserProfileUseCase
|
|
ListUsersUseCase *useCases.ListUsersUseCase
|
|
CreateInviteUseCase *useCases.CreateInviteUseCase
|
|
CancelInviteUseCase *useCases.CancelInviteUseCase
|
|
RenewInviteUseCase *useCases.RenewInviteUseCase
|
|
ListUsersAndInvitesUseCase *useCases.ListUsersAndInvitesUseCase
|
|
GetInviteUseCase *useCases.GetInviteUseCase
|
|
AcceptInviteUseCase *useCases.AcceptInviteUseCase
|
|
SendMailUseCase *useCases.SendMailUseCase
|
|
CreateImageUseCase *useCases.CreateImageUseCase
|
|
ListMediaUseCase *useCases.ListMediaUseCase
|
|
RenameMediaUseCase *useCases.RenameMediaUseCase
|
|
DeleteMediaUseCase *useCases.DeleteMediaUseCase
|
|
MergeMediaUseCase *useCases.MergeMediaUseCase
|
|
GetMediaUsageUseCase *useCases.GetMediaUsageUseCase
|
|
GetSettingsUseCase *useCases.GetSettingsUseCase
|
|
}
|
|
|
|
type Repositories struct {
|
|
ArticleRepo domainArticle.Repository
|
|
UserRepo domainUser.Repository
|
|
ImageRepo domainImage.Repository
|
|
InviteRepo domainInvite.Repository
|
|
MailRepo domainMail.Repository
|
|
}
|
|
|
|
const sqliteBusyTimeoutMs = 5000
|
|
|
|
func SQLiteDSN(dbName string) string {
|
|
return fmt.Sprintf("%s?_pragma=busy_timeout(%d)", dbName, sqliteBusyTimeoutMs)
|
|
}
|
|
|
|
func getDb(dbName string, uploadDir string) *gorm.DB {
|
|
if err := os.MkdirAll(filepath.Dir(dbName), os.ModePerm); err != nil {
|
|
panic("Unable to create necessary subdirectories: " + err.Error())
|
|
}
|
|
db, err := gorm.Open(sqlite.Open(SQLiteDSN(dbName)), &gorm.Config{})
|
|
if err != nil {
|
|
panic("Unable to open the database: " + err.Error())
|
|
}
|
|
|
|
if err := db.AutoMigrate(&models.Article{}, &models.Image{}, &models.User{}, &models.Invite{}); err != nil {
|
|
panic("Failed to migrate database: " + err.Error())
|
|
}
|
|
|
|
if err := persistence.BackfillUserRoles(db); err != nil {
|
|
panic("Failed to backfill user roles: " + err.Error())
|
|
}
|
|
|
|
if err := persistence.BackfillImageMetadata(db, uploadDir); err != nil {
|
|
panic("Failed to backfill image metadata: " + err.Error())
|
|
}
|
|
|
|
return db
|
|
}
|
|
|
|
func getRepositories(db *gorm.DB, settings config.Settings) *Repositories {
|
|
return &Repositories{
|
|
ArticleRepo: persistence.NewArticleRepository(db),
|
|
UserRepo: persistence.NewUserRepository(db),
|
|
ImageRepo: persistence.NewImageRepository(db, settings.UploadDir),
|
|
InviteRepo: persistence.NewInviteRepository(db),
|
|
MailRepo: mailer.NewMailRepository(settings.Smtp),
|
|
}
|
|
}
|
|
|
|
func getUseCases(repos *Repositories, settings config.Settings) *UseCases {
|
|
hasher := hashing.NewBcryptHasher()
|
|
|
|
return &UseCases{
|
|
Token: jwtauth.New("HS256", []byte(settings.JWTSecret), nil),
|
|
CreateArticleUseCase: useCases.NewCreateArticleUseCase(repos.ArticleRepo),
|
|
GetArticleUseCase: useCases.NewGetArticleUseCase(repos.ArticleRepo),
|
|
ListArticlesUseCase: useCases.NewListArticlesUseCase(repos.ArticleRepo),
|
|
UpdateArticleUseCase: useCases.NewUpdateArticleUseCase(repos.ArticleRepo),
|
|
DeleteArticleUseCase: useCases.NewDeleteArticleUseCase(repos.ArticleRepo),
|
|
GetUserUseCase: useCases.NewGetUserUseCase(repos.UserRepo),
|
|
CreateUserUseCase: useCases.NewCreateUserUseCase(repos.UserRepo, hasher, repos.MailRepo, settings.PublicURL),
|
|
AuthenticateUserUseCase: useCases.NewAuthenticateUserUseCase(repos.UserRepo, hasher),
|
|
VerifyUserUseCase: useCases.NewVerifyUserUseCase(repos.UserRepo, hasher),
|
|
CancelRegistrationUseCase: useCases.NewCancelRegistrationUseCase(repos.UserRepo),
|
|
RequestPasswordResetUseCase: useCases.NewRequestPasswordResetUseCase(repos.UserRepo, hasher, repos.MailRepo, settings.PublicURL),
|
|
ResetPasswordUseCase: useCases.NewResetPasswordUseCase(repos.UserRepo, hasher),
|
|
UpdateUserProfileUseCase: useCases.NewUpdateUserProfileUseCase(repos.UserRepo),
|
|
ListUsersUseCase: useCases.NewListUsersUseCase(repos.UserRepo),
|
|
CreateInviteUseCase: useCases.NewCreateInviteUseCase(repos.UserRepo, repos.InviteRepo, hasher, repos.MailRepo, settings.PublicURL),
|
|
CancelInviteUseCase: useCases.NewCancelInviteUseCase(repos.InviteRepo),
|
|
RenewInviteUseCase: useCases.NewRenewInviteUseCase(repos.UserRepo, repos.InviteRepo, hasher, repos.MailRepo, settings.PublicURL),
|
|
ListUsersAndInvitesUseCase: useCases.NewListUsersAndInvitesUseCase(repos.UserRepo, repos.InviteRepo),
|
|
GetInviteUseCase: useCases.NewGetInviteUseCase(repos.InviteRepo, hasher),
|
|
AcceptInviteUseCase: useCases.NewAcceptInviteUseCase(repos.UserRepo, repos.InviteRepo, hasher),
|
|
SendMailUseCase: useCases.NewSendMailUseCase(repos.MailRepo),
|
|
CreateImageUseCase: useCases.NewCreateImageUseCase(repos.ImageRepo),
|
|
ListMediaUseCase: useCases.NewListMediaUseCase(repos.ImageRepo, repos.ArticleRepo, repos.UserRepo),
|
|
RenameMediaUseCase: useCases.NewRenameMediaUseCase(repos.ImageRepo),
|
|
DeleteMediaUseCase: useCases.NewDeleteMediaUseCase(repos.ImageRepo),
|
|
MergeMediaUseCase: useCases.NewMergeMediaUseCase(repos.ImageRepo, repos.ArticleRepo),
|
|
GetMediaUsageUseCase: useCases.NewGetMediaUsageUseCase(repos.ImageRepo, repos.ArticleRepo),
|
|
GetSettingsUseCase: useCases.NewGetSettingsUseCase(settings.Version),
|
|
}
|
|
}
|
|
|
|
func InitContainer(settings config.Settings) (*UseCases, func() error) {
|
|
db := getDb(settings.DBFile, settings.UploadDir)
|
|
repos := getRepositories(db, settings)
|
|
return getUseCases(repos, settings), closeDb(db)
|
|
}
|
|
|
|
func closeDb(db *gorm.DB) func() error {
|
|
return func() error {
|
|
sqlDb, err := db.DB()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return sqlDb.Close()
|
|
}
|
|
}
|