Compare commits
	
		
			3 Commits
		
	
	
		
			5ce0e33359
			...
			ed8afe8324
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ed8afe8324 | |||
| ecc2bff9a0 | |||
| e1f1cd5130 | 
| @@ -1,6 +1,7 @@ | |||||||
| package api | package api | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -41,6 +42,7 @@ func createArticle(c *fiber.Ctx) error { | |||||||
| 		InvisibleUsers []uint            `json:"invisible_users_list"` | 		InvisibleUsers []uint            `json:"invisible_users_list"` | ||||||
| 		Visibility     *int8             `json:"visibility"` | 		Visibility     *int8             `json:"visibility"` | ||||||
| 		IsDraft        bool              `json:"is_draft"` | 		IsDraft        bool              `json:"is_draft"` | ||||||
|  | 		Realm          *uint             `json:"realm"` | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := exts.BindAndValidate(c, &data); err != nil { | 	if err := exts.BindAndValidate(c, &data); err != nil { | ||||||
| @@ -83,6 +85,13 @@ func createArticle(c *fiber.Ctx) error { | |||||||
| 		item.PublishedAt = lo.ToPtr(time.Now()) | 		item.PublishedAt = lo.ToPtr(time.Now()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if data.Realm != nil { | ||||||
|  | 		if _, err := authkit.GetRealmMember(gap.Nx, *data.Realm, user.ID); err != nil { | ||||||
|  | 			return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("you are not a member of realm #%d", *data.Realm)) | ||||||
|  | 		} | ||||||
|  | 		item.RealmID = data.Realm | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if data.Visibility != nil { | 	if data.Visibility != nil { | ||||||
| 		item.Visibility = *data.Visibility | 		item.Visibility = *data.Visibility | ||||||
| 	} else { | 	} else { | ||||||
|   | |||||||
| @@ -55,6 +55,10 @@ func UniversalPostFilter(c *fiber.Ctx, tx *gorm.DB) (*gorm.DB, error) { | |||||||
| 		tx = services.FilterPostWithType(tx, c.Query("type")) | 		tx = services.FilterPostWithType(tx, c.Query("type")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if len(c.Query("realm")) > 0 { | ||||||
|  | 		tx = services.FilterPostWithRealm(tx, c.Query("realm")) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return tx, nil | 	return tx, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,6 +43,7 @@ func createQuestion(c *fiber.Ctx) error { | |||||||
| 		InvisibleUsers []uint            `json:"invisible_users_list"` | 		InvisibleUsers []uint            `json:"invisible_users_list"` | ||||||
| 		Visibility     *int8             `json:"visibility"` | 		Visibility     *int8             `json:"visibility"` | ||||||
| 		IsDraft        bool              `json:"is_draft"` | 		IsDraft        bool              `json:"is_draft"` | ||||||
|  | 		Realm          *uint             `json:"realm"` | ||||||
| 		Reward         float64           `json:"reward"` | 		Reward         float64           `json:"reward"` | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -109,6 +110,13 @@ func createQuestion(c *fiber.Ctx) error { | |||||||
| 		item.PublishedAt = lo.ToPtr(time.Now()) | 		item.PublishedAt = lo.ToPtr(time.Now()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if data.Realm != nil { | ||||||
|  | 		if _, err := authkit.GetRealmMember(gap.Nx, *data.Realm, user.ID); err != nil { | ||||||
|  | 			return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("you are not a member of realm #%d", *data.Realm)) | ||||||
|  | 		} | ||||||
|  | 		item.RealmID = data.Realm | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if data.Visibility != nil { | 	if data.Visibility != nil { | ||||||
| 		item.Visibility = *data.Visibility | 		item.Visibility = *data.Visibility | ||||||
| 	} else { | 	} else { | ||||||
|   | |||||||
| @@ -45,6 +45,7 @@ func createStory(c *fiber.Ctx) error { | |||||||
| 		ReplyTo        *uint             `json:"reply_to"` | 		ReplyTo        *uint             `json:"reply_to"` | ||||||
| 		RepostTo       *uint             `json:"repost_to"` | 		RepostTo       *uint             `json:"repost_to"` | ||||||
| 		Poll           *uint             `json:"poll"` | 		Poll           *uint             `json:"poll"` | ||||||
|  | 		Realm          *uint             `json:"realm"` | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := exts.BindAndValidate(c, &data); err != nil { | 	if err := exts.BindAndValidate(c, &data); err != nil { | ||||||
| @@ -96,6 +97,13 @@ func createStory(c *fiber.Ctx) error { | |||||||
| 		item.Visibility = models.PostVisibilityAll | 		item.Visibility = models.PostVisibilityAll | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if data.Realm != nil { | ||||||
|  | 		if _, err := authkit.GetRealmMember(gap.Nx, *data.Realm, user.ID); err != nil { | ||||||
|  | 			return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("you are not a member of realm #%d", *data.Realm)) | ||||||
|  | 		} | ||||||
|  | 		item.RealmID = data.Realm | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if data.ReplyTo != nil { | 	if data.ReplyTo != nil { | ||||||
| 		var replyTo models.Post | 		var replyTo models.Post | ||||||
| 		if err := database.C.Where("id = ?", data.ReplyTo).First(&replyTo).Error; err != nil { | 		if err := database.C.Where("id = ?", data.ReplyTo).First(&replyTo).Error; err != nil { | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| package api | package api | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -41,6 +42,7 @@ func createVideo(c *fiber.Ctx) error { | |||||||
| 		InvisibleUsers []uint            `json:"invisible_users_list"` | 		InvisibleUsers []uint            `json:"invisible_users_list"` | ||||||
| 		Visibility     *int8             `json:"visibility"` | 		Visibility     *int8             `json:"visibility"` | ||||||
| 		IsDraft        bool              `json:"is_draft"` | 		IsDraft        bool              `json:"is_draft"` | ||||||
|  | 		Realm          *uint             `json:"realm"` | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := exts.BindAndValidate(c, &data); err != nil { | 	if err := exts.BindAndValidate(c, &data); err != nil { | ||||||
| @@ -84,6 +86,13 @@ func createVideo(c *fiber.Ctx) error { | |||||||
| 		item.PublishedAt = lo.ToPtr(time.Now()) | 		item.PublishedAt = lo.ToPtr(time.Now()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if data.Realm != nil { | ||||||
|  | 		if _, err := authkit.GetRealmMember(gap.Nx, *data.Realm, user.ID); err != nil { | ||||||
|  | 			return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("you are not a member of realm #%d", *data.Realm)) | ||||||
|  | 		} | ||||||
|  | 		item.RealmID = data.Realm | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if data.Visibility != nil { | 	if data.Visibility != nil { | ||||||
| 		item.Visibility = *data.Visibility | 		item.Visibility = *data.Visibility | ||||||
| 	} else { | 	} else { | ||||||
|   | |||||||
| @@ -32,8 +32,8 @@ type Post struct { | |||||||
| 	Type        string            `json:"type"` | 	Type        string            `json:"type"` | ||||||
| 	Body        datatypes.JSONMap `json:"body" gorm:"index:,type:gin"` | 	Body        datatypes.JSONMap `json:"body" gorm:"index:,type:gin"` | ||||||
| 	Language    string            `json:"language"` | 	Language    string            `json:"language"` | ||||||
| 	Alias       *string           `json:"alias"` | 	Alias       *string           `json:"alias" gorm:"index"` | ||||||
| 	AliasPrefix *string           `json:"alias_prefix"` | 	AliasPrefix *string           `json:"alias_prefix" gorm:"index"` | ||||||
| 	Tags        []Tag             `json:"tags" gorm:"many2many:post_tags"` | 	Tags        []Tag             `json:"tags" gorm:"many2many:post_tags"` | ||||||
| 	Categories  []Category        `json:"categories" gorm:"many2many:post_categories"` | 	Categories  []Category        `json:"categories" gorm:"many2many:post_categories"` | ||||||
| 	Reactions   []Reaction        `json:"reactions"` | 	Reactions   []Reaction        `json:"reactions"` | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"git.solsynth.dev/hypernet/nexus/pkg/nex" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| @@ -15,6 +16,7 @@ import ( | |||||||
| 	pproto "git.solsynth.dev/hypernet/paperclip/pkg/proto" | 	pproto "git.solsynth.dev/hypernet/paperclip/pkg/proto" | ||||||
| 	"git.solsynth.dev/hypernet/passport/pkg/authkit" | 	"git.solsynth.dev/hypernet/passport/pkg/authkit" | ||||||
| 	authm "git.solsynth.dev/hypernet/passport/pkg/authkit/models" | 	authm "git.solsynth.dev/hypernet/passport/pkg/authkit/models" | ||||||
|  | 	aproto "git.solsynth.dev/hypernet/passport/pkg/proto" | ||||||
| 	"github.com/eko/gocache/lib/v4/cache" | 	"github.com/eko/gocache/lib/v4/cache" | ||||||
| 	"github.com/eko/gocache/lib/v4/marshaler" | 	"github.com/eko/gocache/lib/v4/marshaler" | ||||||
| 	"github.com/eko/gocache/lib/v4/store" | 	"github.com/eko/gocache/lib/v4/store" | ||||||
| @@ -29,7 +31,7 @@ import ( | |||||||
|  |  | ||||||
| func FilterPostWithUserContext(tx *gorm.DB, user *authm.Account) *gorm.DB { | func FilterPostWithUserContext(tx *gorm.DB, user *authm.Account) *gorm.DB { | ||||||
| 	if user == nil { | 	if user == nil { | ||||||
| 		return tx.Where("visibility = ?", models.PostVisibilityAll) | 		return tx.Where("visibility = ? AND realm_id IS NULL", models.PostVisibilityAll) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	const ( | 	const ( | ||||||
| @@ -40,15 +42,16 @@ func FilterPostWithUserContext(tx *gorm.DB, user *authm.Account) *gorm.DB { | |||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	type userContextState struct { | 	type userContextState struct { | ||||||
| 		Allowlist     []uint | 		Allowlist     []uint `json:"allow"` | ||||||
| 		InvisibleList []uint | 		InvisibleList []uint `json:"invisible"` | ||||||
|  | 		RealmList     []uint `json:"realm"` | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cacheManager := cache.New[any](localCache.S) | 	cacheManager := cache.New[any](localCache.S) | ||||||
| 	marshal := marshaler.New(cacheManager) | 	marshal := marshaler.New(cacheManager) | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
|  |  | ||||||
| 	var allowlist, invisibleList []uint | 	var allowlist, invisibleList, realmList []uint | ||||||
|  |  | ||||||
| 	statusCacheKey := fmt.Sprintf("post-user-context-query#%d", user.ID) | 	statusCacheKey := fmt.Sprintf("post-user-context-query#%d", user.ID) | ||||||
| 	statusCache, err := marshal.Get(ctx, statusCacheKey, new(userContextState)) | 	statusCache, err := marshal.Get(ctx, statusCacheKey, new(userContextState)) | ||||||
| @@ -56,10 +59,31 @@ func FilterPostWithUserContext(tx *gorm.DB, user *authm.Account) *gorm.DB { | |||||||
| 		state := statusCache.(*userContextState) | 		state := statusCache.(*userContextState) | ||||||
| 		allowlist = state.Allowlist | 		allowlist = state.Allowlist | ||||||
| 		invisibleList = state.InvisibleList | 		invisibleList = state.InvisibleList | ||||||
|  | 		realmList = state.RealmList | ||||||
| 	} else { | 	} else { | ||||||
|  | 		// Getting the relationships | ||||||
| 		userFriends, _ := authkit.ListRelative(gap.Nx, user.ID, int32(authm.RelationshipFriend), true) | 		userFriends, _ := authkit.ListRelative(gap.Nx, user.ID, int32(authm.RelationshipFriend), true) | ||||||
| 		userGotBlocked, _ := authkit.ListRelative(gap.Nx, user.ID, int32(authm.RelationshipBlocked), true) | 		userGotBlocked, _ := authkit.ListRelative(gap.Nx, user.ID, int32(authm.RelationshipBlocked), true) | ||||||
| 		userBlocked, _ := authkit.ListRelative(gap.Nx, user.ID, int32(authm.RelationshipBlocked), false) | 		userBlocked, _ := authkit.ListRelative(gap.Nx, user.ID, int32(authm.RelationshipBlocked), false) | ||||||
|  |  | ||||||
|  | 		// Getting the realm list | ||||||
|  | 		{ | ||||||
|  | 			conn, err := gap.Nx.GetClientGrpcConn(nex.ServiceTypeAuth) | ||||||
|  | 			if err != nil { | ||||||
|  | 				ac := aproto.NewRealmServiceClient(conn) | ||||||
|  | 				ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) | ||||||
|  | 				defer cancel() | ||||||
|  | 				resp, err := ac.ListAvailableRealm(ctx, &aproto.LookupUserRealmRequest{ | ||||||
|  | 					UserId: uint64(user.ID), | ||||||
|  | 				}) | ||||||
|  | 				if err == nil { | ||||||
|  | 					realmList = lo.Map(resp.GetData(), func(item *aproto.RealmInfo, index int) uint { | ||||||
|  | 						return uint(item.GetId()) | ||||||
|  | 					}) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		userFriendList := lo.Map(userFriends, func(item *proto.UserInfo, index int) uint { | 		userFriendList := lo.Map(userFriends, func(item *proto.UserInfo, index int) uint { | ||||||
| 			return uint(item.GetId()) | 			return uint(item.GetId()) | ||||||
| 		}) | 		}) | ||||||
| @@ -101,6 +125,7 @@ func FilterPostWithUserContext(tx *gorm.DB, user *authm.Account) *gorm.DB { | |||||||
| 			userContextState{ | 			userContextState{ | ||||||
| 				Allowlist:     allowlist, | 				Allowlist:     allowlist, | ||||||
| 				InvisibleList: invisibleList, | 				InvisibleList: invisibleList, | ||||||
|  | 				RealmList:     realmList, | ||||||
| 			}, | 			}, | ||||||
| 			store.WithExpiration(5*time.Minute), | 			store.WithExpiration(5*time.Minute), | ||||||
| 			store.WithTags([]string{"post-user-context-query", fmt.Sprintf("user#%d", user.ID)}), | 			store.WithTags([]string{"post-user-context-query", fmt.Sprintf("user#%d", user.ID)}), | ||||||
| @@ -125,10 +150,28 @@ func FilterPostWithUserContext(tx *gorm.DB, user *authm.Account) *gorm.DB { | |||||||
| 	if len(invisibleList) > 0 { | 	if len(invisibleList) > 0 { | ||||||
| 		tx = tx.Where("publisher_id NOT IN ?", invisibleList) | 		tx = tx.Where("publisher_id NOT IN ?", invisibleList) | ||||||
| 	} | 	} | ||||||
|  | 	if len(realmList) > 0 { | ||||||
|  | 		tx = tx.Where("realm_id IN ?", realmList) | ||||||
|  | 	} else { | ||||||
|  | 		tx = tx.Where("realm_id IS NULL") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return tx | 	return tx | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func FilterPostWithRealm(tx *gorm.DB, probe string) *gorm.DB { | ||||||
|  | 	if numericId, err := strconv.Atoi(probe); err == nil { | ||||||
|  | 		return tx.Where("realm_id = ?", uint(numericId)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	realm, err := authkit.GetRealmByAlias(gap.Nx, probe) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return tx | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return tx.Where("realm_id = ?", realm.ID) | ||||||
|  | } | ||||||
|  |  | ||||||
| func FilterPostWithCategory(tx *gorm.DB, alias string) *gorm.DB { | func FilterPostWithCategory(tx *gorm.DB, alias string) *gorm.DB { | ||||||
| 	aliases := strings.Split(alias, ",") | 	aliases := strings.Split(alias, ",") | ||||||
| 	return tx.Joins("JOIN post_categories ON posts.id = post_categories.post_id"). | 	return tx.Joins("JOIN post_categories ON posts.id = post_categories.post_id"). | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user