Files
RenewCMS/internal/infrastructure/useCases/authorSupport.go
T

116 lines
3.0 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/audit"
"RenewCMS/internal/domain/author"
"RenewCMS/internal/domain/image"
"RenewCMS/internal/domain/user"
"errors"
"strconv"
"strings"
)
const authorChangeSeparator = ", "
type AuthorCaller struct {
UserID uint32
Role user.Role
}
func isAdminRole(role user.Role) bool {
return role == user.RoleOwner || role == user.RoleAdmin
}
func (c AuthorCaller) isAdmin() bool {
return isAdminRole(c.Role)
}
func authorTarget(a author.Author) audit.Target {
return audit.NewTarget(audit.TargetAuthor, a.ID, a.Name)
}
func isSlugTaken(authors author.Repository, slug string) (bool, error) {
_, err := authors.GetBySlug(slug)
if errors.Is(err, author.ErrAuthorNotFound) {
return false, nil
}
return err == nil, err
}
func ensureUserCanBeLinked(users user.Repository, authors author.Repository, userID uint32) error {
if _, err := users.Get(userID); err != nil {
return err
}
_, err := authors.GetByUserID(userID)
if err == nil {
return author.ErrUserAlreadyLinked
}
if errors.Is(err, author.ErrAuthorNotFound) {
return nil
}
return err
}
func withUserEmail(users user.Repository, a author.Author) author.Author {
a.UserEmail = nil
if a.UserID == nil {
return a
}
linked, err := users.Get(*a.UserID)
if err != nil {
return a
}
email := linked.Email
a.UserEmail = &email
return a
}
func linksLabel(links []author.SocialLink) string {
labels := make([]string, 0, len(links))
for _, link := range links {
labels = append(labels, link.Type+": "+link.URL)
}
return strings.Join(labels, authorChangeSeparator)
}
func websiteLabel(website *string) string {
if website == nil {
return ""
}
return *website
}
func usernameLabel(users user.Repository, id *uint32) string {
if id == nil {
return ""
}
found, err := users.Get(*id)
if err != nil {
return strconv.FormatUint(uint64(*id), 10)
}
return found.Username
}
func sameID(a *uint32, b *uint32) bool {
if a == nil || b == nil {
return a == b
}
return *a == *b
}
func authorChanges(users user.Repository, images image.Repository, before author.Author, after author.Author) []audit.Change {
changes := []audit.Change{}
changes = audit.AppendTextChange(changes, audit.FieldName, before.Name, after.Name)
changes = audit.AppendTextChange(changes, audit.FieldSlug, before.Slug, after.Slug)
changes = audit.AppendTextChange(changes, audit.FieldBio, before.Bio, after.Bio)
changes = audit.AppendTextChange(changes, audit.FieldWebsite, websiteLabel(before.Website), websiteLabel(after.Website))
changes = audit.AppendTextChange(changes, audit.FieldSocialLinks, linksLabel(before.SocialLinks), linksLabel(after.SocialLinks))
if !sameID(before.AvatarID, after.AvatarID) {
changes = append(changes, audit.TextChange(audit.FieldAvatar, imageLabel(images, before.AvatarID), imageLabel(images, after.AvatarID)))
}
if !sameID(before.UserID, after.UserID) {
changes = append(changes, audit.TextChange(audit.FieldUser, usernameLabel(users, before.UserID), usernameLabel(users, after.UserID)))
}
return changes
}