129 lines
3.2 KiB
Go
129 lines
3.2 KiB
Go
package sites
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"emperror.dev/errors"
|
|
"github.com/go-ozzo/ozzo-validation/v4"
|
|
"github.com/gofiber/fiber/v3"
|
|
"lmika.dev/lmika/weiro/models"
|
|
"lmika.dev/lmika/weiro/providers/db"
|
|
)
|
|
|
|
type Service struct {
|
|
db *db.Provider
|
|
}
|
|
|
|
func New(dbp *db.Provider) *Service {
|
|
return &Service{
|
|
db: dbp,
|
|
}
|
|
}
|
|
|
|
func (s *Service) HasUsersAsSites(ctx context.Context) (bool, error) {
|
|
return s.db.HasUsersAndSites(ctx)
|
|
}
|
|
|
|
func (s *Service) BestSite(ctx context.Context, user models.User) (models.Site, error) {
|
|
sites, err := s.db.SelectSitesOwnedByUser(ctx, user.ID)
|
|
if err != nil {
|
|
return models.Site{}, err
|
|
} else if len(sites) == 0 {
|
|
return models.Site{}, errors.New("no sites found")
|
|
}
|
|
|
|
return sites[0], nil
|
|
}
|
|
|
|
type FirstRunRequest struct {
|
|
Username string `form:"username"`
|
|
Password1 string `form:"password1"`
|
|
Password2 string `form:"password2"`
|
|
SiteName string `form:"siteName"`
|
|
SiteURL string `form:"siteUrl"`
|
|
NetlifySiteID string `form:"netlifySiteId"`
|
|
NetlifyAPIKey string `form:"netlifyAPIToken"`
|
|
}
|
|
|
|
func (frr FirstRunRequest) Validate() error {
|
|
return validation.ValidateStruct(&frr,
|
|
validation.Field(&frr.Username, validation.Required, validation.Match(models.ValidUserName)),
|
|
validation.Field(&frr.Password1, validation.Required),
|
|
validation.Field(&frr.Password2, validation.Required, validation.By(stringEquals(frr.Password1))),
|
|
)
|
|
}
|
|
|
|
func (s *Service) FirstRun(ctx context.Context, req FirstRunRequest) (newUser models.User, newSite models.Site, _ error) {
|
|
if err := req.Validate(); err != nil {
|
|
return newUser, newSite, err
|
|
}
|
|
|
|
hasSite, err := s.db.HasUsersAndSites(ctx)
|
|
if err != nil {
|
|
return newUser, newSite, err
|
|
} else if hasSite {
|
|
return newUser, newSite, errors.New("user and site already exists")
|
|
}
|
|
|
|
newUser = models.User{
|
|
Username: req.Username,
|
|
TimeZone: "UTC",
|
|
Created: time.Now(),
|
|
}
|
|
newUser.SetPassword(req.Password1)
|
|
if err := s.db.SaveUser(ctx, &newUser); err != nil {
|
|
return newUser, newSite, err
|
|
}
|
|
|
|
newSite = models.Site{
|
|
Title: defaultIfEmpty(req.SiteName, "New Site"),
|
|
GUID: models.NewNanoID(),
|
|
OwnerID: newUser.ID,
|
|
Created: time.Now(),
|
|
}
|
|
if err := s.db.SaveSite(ctx, &newSite); err != nil {
|
|
return newUser, newSite, err
|
|
}
|
|
|
|
hasNetlifyConfig := req.SiteURL != "" && req.NetlifySiteID != "" && req.NetlifyAPIKey != ""
|
|
if hasNetlifyConfig {
|
|
target := models.SitePublishTarget{
|
|
SiteID: newSite.ID,
|
|
Enabled: true,
|
|
GUID: models.NewNanoID(),
|
|
BaseURL: req.SiteURL,
|
|
TargetType: "netlify",
|
|
TargetRef: req.NetlifySiteID,
|
|
TargetKey: req.NetlifyAPIKey,
|
|
}
|
|
if err := s.db.SavePublishTarget(ctx, &target); err != nil {
|
|
return newUser, newSite, err
|
|
}
|
|
}
|
|
|
|
return newUser, newSite, nil
|
|
}
|
|
|
|
func (s *Service) GetSiteByID(ctx context.Context, siteID int64) (models.Site, error) {
|
|
user, ok := models.GetUser(ctx)
|
|
if !ok {
|
|
return models.Site{}, models.UserRequiredError
|
|
}
|
|
|
|
site, err := s.db.SelectSiteByID(ctx, siteID)
|
|
if err != nil {
|
|
return models.Site{}, err
|
|
}
|
|
|
|
if site.OwnerID != user.ID {
|
|
return models.Site{}, fiber.ErrForbidden
|
|
}
|
|
|
|
return site, nil
|
|
}
|
|
|
|
func (s *Service) ListAllSitesWithOwners(ctx context.Context) ([]db.SiteWithOwner, error) {
|
|
return s.db.SelectAllSitesWithOwners(ctx)
|
|
}
|