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)
|
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 未发布内容仅允许作者或租户管理员查看。
|
if err := s.ensureContentReadable(ctx, userID, &item); err != nil {
|
||||||
if item.Status != consts.ContentStatusPublished {
|
return nil, err
|
||||||
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("内容未发布")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment Views
|
// 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) {
|
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 {
|
if tenantID > 0 {
|
||||||
_, err := models.ContentQuery.WithContext(ctx).
|
contentQuery = contentQuery.Where(models.ContentQuery.TenantID.Eq(tenantID))
|
||||||
Where(models.ContentQuery.ID.Eq(id), models.ContentQuery.TenantID.Eq(tenantID)).
|
}
|
||||||
First()
|
content, err := contentQuery.First()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, errorx.ErrRecordNotFound
|
return nil, errorx.ErrRecordNotFound
|
||||||
}
|
|
||||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
|
||||||
}
|
}
|
||||||
|
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||||
|
}
|
||||||
|
if err := s.ensureContentReadable(ctx, userID, content); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tbl, q := models.CommentQuery.QueryContext(ctx)
|
tbl, q := models.CommentQuery.QueryContext(ctx)
|
||||||
@@ -354,6 +344,9 @@ func (s *content) CreateComment(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errorx.ErrRecordNotFound
|
return errorx.ErrRecordNotFound
|
||||||
}
|
}
|
||||||
|
if err := s.ensureContentReadable(ctx, userID, c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
comment := &models.Comment{
|
comment := &models.Comment{
|
||||||
TenantID: c.TenantID,
|
TenantID: c.TenantID,
|
||||||
@@ -384,6 +377,20 @@ func (s *content) LikeComment(ctx context.Context, tenantID, userID, id int64) e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errorx.ErrRecordNotFound
|
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 {
|
err = models.Q.Transaction(func(tx *models.Query) error {
|
||||||
exists, _ := tx.UserCommentAction.WithContext(ctx).
|
exists, _ := tx.UserCommentAction.WithContext(ctx).
|
||||||
@@ -610,6 +617,31 @@ func (s *content) toContentItemDTO(item *models.Content, price float64, authorIs
|
|||||||
return dto
|
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 {
|
func (s *content) toMediaURLs(assets []*models.ContentAsset) []content_dto.MediaURL {
|
||||||
var urls []content_dto.MediaURL
|
var urls []content_dto.MediaURL
|
||||||
for _, ca := range assets {
|
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))
|
query = query.Where(models.ContentQuery.TenantID.Eq(tenantID))
|
||||||
}
|
}
|
||||||
c, err := query.
|
c, err := query.
|
||||||
Select(models.ContentQuery.UserID, models.ContentQuery.Title).
|
Select(models.ContentQuery.UserID, models.ContentQuery.Title, models.ContentQuery.Status, models.ContentQuery.TenantID).
|
||||||
First()
|
First()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorx.ErrRecordNotFound
|
return errorx.ErrRecordNotFound
|
||||||
}
|
}
|
||||||
|
if err := s.ensureContentReadable(ctx, userID, c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = models.Q.Transaction(func(tx *models.Query) error {
|
err = models.Q.Transaction(func(tx *models.Query) error {
|
||||||
exists, _ := tx.UserContentAction.WithContext(ctx).
|
exists, _ := tx.UserContentAction.WithContext(ctx).
|
||||||
|
|||||||
Reference in New Issue
Block a user