fix: block interactions on unpublished content
This commit is contained in:
@@ -157,21 +157,8 @@ func (s *content) Get(ctx context.Context, tenantID, userID, id int64) (*content
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
|
||||
// 未发布内容仅允许作者或租户管理员查看。
|
||||
if item.Status != consts.ContentStatusPublished {
|
||||
if userID == 0 {
|
||||
return nil, errorx.ErrForbidden.WithMsg("内容未发布")
|
||||
}
|
||||
if item.UserID != userID {
|
||||
exists, _ := models.TenantUserQuery.WithContext(ctx).
|
||||
Where(models.TenantUserQuery.TenantID.Eq(item.TenantID),
|
||||
models.TenantUserQuery.UserID.Eq(userID),
|
||||
models.TenantUserQuery.Role.Contains(types.Array[consts.TenantUserRole]{consts.TenantUserRoleTenantAdmin})).
|
||||
Exists()
|
||||
if !exists {
|
||||
return nil, errorx.ErrForbidden.WithMsg("内容未发布")
|
||||
}
|
||||
}
|
||||
if err := s.ensureContentReadable(ctx, userID, &item); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Increment Views
|
||||
@@ -263,16 +250,19 @@ func (s *content) Get(ctx context.Context, tenantID, userID, id int64) (*content
|
||||
}
|
||||
|
||||
func (s *content) ListComments(ctx context.Context, tenantID, userID, id int64, page int) (*requests.Pager, error) {
|
||||
contentQuery := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(id))
|
||||
if tenantID > 0 {
|
||||
_, err := models.ContentQuery.WithContext(ctx).
|
||||
Where(models.ContentQuery.ID.Eq(id), models.ContentQuery.TenantID.Eq(tenantID)).
|
||||
First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
}
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
contentQuery = contentQuery.Where(models.ContentQuery.TenantID.Eq(tenantID))
|
||||
}
|
||||
content, err := contentQuery.First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errorx.ErrRecordNotFound
|
||||
}
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
if err := s.ensureContentReadable(ctx, userID, content); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tbl, q := models.CommentQuery.QueryContext(ctx)
|
||||
@@ -354,6 +344,9 @@ func (s *content) CreateComment(
|
||||
if err != nil {
|
||||
return errorx.ErrRecordNotFound
|
||||
}
|
||||
if err := s.ensureContentReadable(ctx, userID, c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
comment := &models.Comment{
|
||||
TenantID: c.TenantID,
|
||||
@@ -384,6 +377,20 @@ func (s *content) LikeComment(ctx context.Context, tenantID, userID, id int64) e
|
||||
if err != nil {
|
||||
return errorx.ErrRecordNotFound
|
||||
}
|
||||
contentQuery := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(cm.ContentID))
|
||||
if tenantID > 0 {
|
||||
contentQuery = contentQuery.Where(models.ContentQuery.TenantID.Eq(tenantID))
|
||||
}
|
||||
c, err := contentQuery.First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return errorx.ErrRecordNotFound
|
||||
}
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
if err := s.ensureContentReadable(ctx, userID, c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = models.Q.Transaction(func(tx *models.Query) error {
|
||||
exists, _ := tx.UserCommentAction.WithContext(ctx).
|
||||
@@ -610,6 +617,31 @@ func (s *content) toContentItemDTO(item *models.Content, price float64, authorIs
|
||||
return dto
|
||||
}
|
||||
|
||||
func (s *content) ensureContentReadable(ctx context.Context, userID int64, item *models.Content) error {
|
||||
if item.Status == consts.ContentStatusPublished {
|
||||
return nil
|
||||
}
|
||||
// 未发布内容仅允许作者或租户管理员查看。
|
||||
if userID == 0 {
|
||||
return errorx.ErrForbidden.WithMsg("内容未发布")
|
||||
}
|
||||
if item.UserID == userID {
|
||||
return nil
|
||||
}
|
||||
exists, err := models.TenantUserQuery.WithContext(ctx).
|
||||
Where(models.TenantUserQuery.TenantID.Eq(item.TenantID),
|
||||
models.TenantUserQuery.UserID.Eq(userID),
|
||||
models.TenantUserQuery.Role.Contains(types.Array[consts.TenantUserRole]{consts.TenantUserRoleTenantAdmin})).
|
||||
Exists()
|
||||
if err != nil {
|
||||
return errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
if !exists {
|
||||
return errorx.ErrForbidden.WithMsg("内容未发布")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *content) toMediaURLs(assets []*models.ContentAsset) []content_dto.MediaURL {
|
||||
var urls []content_dto.MediaURL
|
||||
for _, ca := range assets {
|
||||
@@ -637,11 +669,14 @@ func (s *content) addInteract(ctx context.Context, tenantID, userID, contentId i
|
||||
query = query.Where(models.ContentQuery.TenantID.Eq(tenantID))
|
||||
}
|
||||
c, err := query.
|
||||
Select(models.ContentQuery.UserID, models.ContentQuery.Title).
|
||||
Select(models.ContentQuery.UserID, models.ContentQuery.Title, models.ContentQuery.Status, models.ContentQuery.TenantID).
|
||||
First()
|
||||
if err != nil {
|
||||
return errorx.ErrRecordNotFound
|
||||
}
|
||||
if err := s.ensureContentReadable(ctx, userID, c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = models.Q.Transaction(func(tx *models.Query) error {
|
||||
exists, _ := tx.UserContentAction.WithContext(ctx).
|
||||
|
||||
Reference in New Issue
Block a user