From 380d3db0bf83ef10565e4a9087ac37d458f03675 Mon Sep 17 00:00:00 2001
From: Michael Jerger <michael.jerger@meissa-gmbh.de>
Date: Fri, 12 Jan 2024 17:00:17 +0100
Subject: [PATCH] integrate federation info in api call

---
 models/forgefed/federationinfo.go            |  1 -
 models/forgefed/federationinfo_repository.go |  4 +-
 routers/api/v1/activitypub/repository.go     | 40 +++++++++++++++-----
 3 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/models/forgefed/federationinfo.go b/models/forgefed/federationinfo.go
index 99018433f9..53f2c3e5e1 100644
--- a/models/forgefed/federationinfo.go
+++ b/models/forgefed/federationinfo.go
@@ -24,7 +24,6 @@ func (info FederationInfo) Validate() []string {
 	var result []string
 	result = append(result, validation.ValidateNotEmpty(string(info.HostFqdn), "HostFqdn")...)
 	result = append(result, validation.ValidateMaxLen(string(info.HostFqdn), 255, "HostFqdn")...)
-	result = append(result, validation.ValidateNotEmpty(info.LatestActivity, "LatestActivity")...)
 	result = append(result, info.NodeInfo.Validate()...)
 
 	return result
diff --git a/models/forgefed/federationinfo_repository.go b/models/forgefed/federationinfo_repository.go
index e2e43e6fc4..d568d7aecc 100644
--- a/models/forgefed/federationinfo_repository.go
+++ b/models/forgefed/federationinfo_repository.go
@@ -29,13 +29,13 @@ func GetFederationInfo(ctx context.Context, ID int64) (*FederationInfo, error) {
 	return info, nil
 }
 
-func GetFederationInfoByHostFqdn(ctx context.Context, fqdn string) (*FederationInfo, error) {
+func FindFederationInfoByHostFqdn(ctx context.Context, fqdn string) (*FederationInfo, error) {
 	info := new(FederationInfo)
 	has, err := db.GetEngine(ctx).Where("host_fqdn=?", fqdn).Get(info)
 	if err != nil {
 		return nil, err
 	} else if !has {
-		return nil, fmt.Errorf("FederationInfo record %v does not exist", fqdn)
+		return nil, nil
 	}
 	if res, err := validation.IsValid(info); !res {
 		return nil, fmt.Errorf("FederationInfo is not valid: %v", err)
diff --git a/routers/api/v1/activitypub/repository.go b/routers/api/v1/activitypub/repository.go
index 005f2c98a3..1c7bababba 100644
--- a/routers/api/v1/activitypub/repository.go
+++ b/routers/api/v1/activitypub/repository.go
@@ -94,17 +94,29 @@ func RepositoryInbox(ctx *context.APIContext) {
 	// parse actorID (person)
 	actorUri := activity.Actor.GetID().String()
 	rawActorID, err := forgefed.NewActorID(actorUri)
-	nodeInfo, err := createNodeInfo(ctx, rawActorID)
-	log.Info("RepositoryInbox: nodeInfo validated: %v", nodeInfo)
+	federationInfo, err := forgefed.FindFederationInfoByHostFqdn(ctx, rawActorID.Host)
+	if err != nil {
+		ctx.ServerError("Error while loading FederationInfo: %v", err)
+		return
+	}
+	if federationInfo == nil {
+		result, err := createFederationInfo(ctx, rawActorID)
+		if err != nil {
+			ctx.ServerError("Validate actorId", err)
+			return
+		}
+		federationInfo = &result
+		log.Info("RepositoryInbox: nodeInfo validated: %v", federationInfo)
+	}
 
-	actorID, err := forgefed.NewPersonID(actorUri, string(nodeInfo.Source))
+	actorID, err := forgefed.NewPersonID(actorUri, string(federationInfo.NodeInfo.Source))
 	if err != nil {
 		ctx.ServerError("Validate actorId", err)
 		return
 	}
 	log.Info("RepositoryInbox: actorId validated: %v", actorID)
 	// parse objectID (repository)
-	objectID, err := forgefed.NewRepositoryID(activity.Object.GetID().String(), string(nodeInfo.Source))
+	objectID, err := forgefed.NewRepositoryID(activity.Object.GetID().String(), string(forgefed.ForgejoSourceType))
 	if err != nil {
 		ctx.ServerError("Validate objectId", err)
 		return
@@ -184,25 +196,33 @@ func SearchUsersByLoginName(loginName string) ([]*user_model.User, error) {
 	return users, nil
 }
 
-func createNodeInfo(ctx *context.APIContext, actorID forgefed.ActorID) (forgefed.NodeInfo, error) {
+func createFederationInfo(ctx *context.APIContext, actorID forgefed.ActorID) (forgefed.FederationInfo, error) {
 	actionsUser := user_model.NewActionsUser()
 	client, err := api.NewClient(ctx, actionsUser, "no idea where to get key material.")
 	if err != nil {
-		return forgefed.NodeInfo{}, err
+		return forgefed.FederationInfo{}, err
 	}
 	body, err := client.GetBody(actorID.AsWellKnownNodeInfoUri())
 	if err != nil {
-		return forgefed.NodeInfo{}, err
+		return forgefed.FederationInfo{}, err
 	}
 	nodeInfoWellKnown, err := forgefed.NewNodeInfoWellKnown(body)
 	if err != nil {
-		return forgefed.NodeInfo{}, err
+		return forgefed.FederationInfo{}, err
 	}
 	body, err = client.GetBody(nodeInfoWellKnown.Href)
 	if err != nil {
-		return forgefed.NodeInfo{}, err
+		return forgefed.FederationInfo{}, err
 	}
-	return forgefed.NewNodeInfo(body)
+	nodeInfo, err := forgefed.NewNodeInfo(body)
+	if err != nil {
+		return forgefed.FederationInfo{}, err
+	}
+	result := forgefed.FederationInfo{
+		HostFqdn: actorID.Host,
+		NodeInfo: nodeInfo,
+	}
+	return result, nil
 }
 
 // ToDo: Maybe use externalLoginUser