diff --git a/activitypub/util.go b/activitypub/util.go index abee15f..bd8c276 100644 --- a/activitypub/util.go +++ b/activitypub/util.go @@ -1,6 +1,11 @@ package activitypub -import "strings" +import ( + "fmt" + "strings" + + "git.mstar.dev/mstar/linstrom/config" +) type InvalidFullHandleError struct { Raw string @@ -17,3 +22,11 @@ func SplitFullHandle(full string) (string, string, error) { } return splits[0], splits[1], nil } + +func UserIdToApUrl(id string) string { + return fmt.Sprintf( + "%s/api/activitypub/user/%s", + config.GlobalConfig.General.GetFullPublicUrl(), + id, + ) +} diff --git a/storage-new/genLinksForUser.go b/storage-new/genLinksForUser.go new file mode 100644 index 0000000..38a5c66 --- /dev/null +++ b/storage-new/genLinksForUser.go @@ -0,0 +1,55 @@ +package storage + +import ( + "database/sql" + "strings" + + "git.mstar.dev/mstar/goutils/other" + "gorm.io/gorm" + + "git.mstar.dev/mstar/linstrom/activitypub" + "git.mstar.dev/mstar/linstrom/config" + "git.mstar.dev/mstar/linstrom/storage-new/dbgen" + "git.mstar.dev/mstar/linstrom/storage-new/models" +) + +func EnsureLocalUserIdHasLinks(id string) error { + if strings.HasPrefix(id, "http") { + return nil + } + u := dbgen.User + user, err := u.Where(u.ID.Eq(id)).Preload(u.RemoteInfo).First() + switch err { + case gorm.ErrRecordNotFound: + return nil + case nil: + default: + return other.Error("storage", "Failed to get user by id", err) + } + if user.RemoteInfo != nil { + return nil + } + apId := activitypub.UserIdToApUrl(id) + info := models.UserRemoteLinks{ + UserId: id, + ApLink: apId, + InboxLink: apId + "/inbox", + ViewLink: sql.NullString{ + Valid: true, + String: config.GlobalConfig.General.GetFullPublicUrl() + "/user/" + user.Username, + }, + FollowersLink: sql.NullString{ + Valid: true, + String: apId + "/followers", + }, + FollowingLink: sql.NullString{ + Valid: true, + String: apId + "/following", + }, + } + err = dbgen.UserRemoteLinks.Create(&info) + if err != nil { + return other.Error("storage", "Failed to store links for account", err) + } + return nil +} diff --git a/storage-new/self.go b/storage-new/self.go index d9db0ef..6c2bdab 100644 --- a/storage-new/self.go +++ b/storage-new/self.go @@ -33,6 +33,9 @@ func InsertSelf() error { if err != nil { return other.Error("storage", "failed to save/update self user", err) } + if err = EnsureLocalUserIdHasLinks(user.ID); err != nil { + return other.Error("storage", "failed to create ap links for self", err) + } ServerActorId = user.ID if err = insertUserPronoun(user); err != nil { return other.Error("storage", "failed to save/update self user pronoun", err) diff --git a/web/debug/users.go b/web/debug/users.go index bc3a592..747782c 100644 --- a/web/debug/users.go +++ b/web/debug/users.go @@ -18,6 +18,7 @@ import ( "git.mstar.dev/mstar/linstrom/activitypub" "git.mstar.dev/mstar/linstrom/shared" + "git.mstar.dev/mstar/linstrom/storage-new" "git.mstar.dev/mstar/linstrom/storage-new/dbgen" "git.mstar.dev/mstar/linstrom/storage-new/models" webshared "git.mstar.dev/mstar/linstrom/web/shared" @@ -175,6 +176,10 @@ func createLocalUser(w http.ResponseWriter, r *http.Request) { log.Error().Err(err).Msg("failed to create new local user") webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError) } + if err = storage.EnsureLocalUserIdHasLinks(user.ID); err != nil { + log.Error().Err(err).Msg("Failed to add links to new user") + webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError) + } } func deleteUser(w http.ResponseWriter, r *http.Request) { diff --git a/web/public/api/activitypub/activityFollow.go b/web/public/api/activitypub/activityFollow.go index 4cb1e36..222dfc3 100644 --- a/web/public/api/activitypub/activityFollow.go +++ b/web/public/api/activitypub/activityFollow.go @@ -84,12 +84,12 @@ func FollowFromStorage(ctx context.Context, id string) (*ActivityFollowOut, erro if follower.RemoteInfo != nil { out.Actor = follower.RemoteInfo.ApLink } else { - out.Actor = userIdToApUrl(follower.ID) + out.Actor = activitypub.UserIdToApUrl(follower.ID) } if followed.RemoteInfo != nil { out.Object = followed.RemoteInfo.ApLink } else { - out.Object = userIdToApUrl(followed.ID) + out.Object = activitypub.UserIdToApUrl(followed.ID) } return &out, nil } diff --git a/web/public/api/activitypub/user.go b/web/public/api/activitypub/user.go index 2fbdcec..e5dcd2f 100644 --- a/web/public/api/activitypub/user.go +++ b/web/public/api/activitypub/user.go @@ -72,7 +72,7 @@ func users(w http.ResponseWriter, r *http.Request) { return } - apUrl := userIdToApUrl(user.ID) + apUrl := activitypub.UserIdToApUrl(user.ID) var keyBytes string if config.GlobalConfig.Experimental.UseEd25519Keys { keyBytes = shared.KeyBytesToPem(user.PublicKeyEd, true) @@ -160,7 +160,7 @@ func userFollowing(w http.ResponseWriter, r *http.Request) { webutils.ProblemDetailsStatusOnly(w, http.StatusNotFound) return } - apUrl := userIdToApUrl(userId) + apUrl := activitypub.UserIdToApUrl(userId) var data []byte followingCount, err := dbgen.UserToUserRelation.CountFollowingForId(userId) if err != nil { @@ -212,7 +212,7 @@ func userFollowing(w http.ResponseWriter, r *http.Request) { Context: "https://www.w3.org/ns/activitystreams", Type: "OrderedCollectionPage", Id: fmt.Sprintf("%s/following?page=%d", apUrl, pageNr), - PartOf: userIdToApUrl(userId) + "/following", + PartOf: activitypub.UserIdToApUrl(userId) + "/following", Items: sliceutils.Map(links, func(t string) any { return t }), } if hasNextPage { @@ -247,7 +247,7 @@ func userFollowers(w http.ResponseWriter, r *http.Request) { webutils.ProblemDetailsStatusOnly(w, http.StatusNotFound) return } - apUrl := userIdToApUrl(userId) + apUrl := activitypub.UserIdToApUrl(userId) var data []byte followersCount, err := dbgen.UserToUserRelation.CountFollowersForId(userId) if err != nil { @@ -300,7 +300,7 @@ func userFollowers(w http.ResponseWriter, r *http.Request) { Context: activitypub.BaseLdContext, Type: "OrderedCollectionPage", Id: fmt.Sprintf("%s/followers?page=%d", apUrl, pageNr), - PartOf: userIdToApUrl(userId) + "/followers", + PartOf: activitypub.UserIdToApUrl(userId) + "/followers", Items: sliceutils.Map(links, func(t string) any { return t }), } if hasNextPage { diff --git a/web/public/api/activitypub/util.go b/web/public/api/activitypub/util.go index ca82986..7c30024 100644 --- a/web/public/api/activitypub/util.go +++ b/web/public/api/activitypub/util.go @@ -1,15 +1 @@ package activitypub - -import ( - "fmt" - - "git.mstar.dev/mstar/linstrom/config" -) - -func userIdToApUrl(id string) string { - return fmt.Sprintf( - "%s/api/activitypub/user/%s", - config.GlobalConfig.General.GetFullPublicUrl(), - id, - ) -}