mirror of
https://codeberg.org/forgejo/forgejo
synced 2024-11-22 09:54:24 +01:00
added repoUri to federationService
This does not work yet. APAPI url OR host and id have to be derived from repoUri.
This commit is contained in:
parent
2b7a22afb3
commit
8cd89bf4d3
|
@ -14,14 +14,18 @@ type FollowingRepo struct {
|
||||||
RepoID int64 `xorm:"NOT NULL"`
|
RepoID int64 `xorm:"NOT NULL"`
|
||||||
ExternalID string `xorm:"TEXT UNIQUE(federation_repo_mapping) NOT NULL"`
|
ExternalID string `xorm:"TEXT UNIQUE(federation_repo_mapping) NOT NULL"`
|
||||||
FederationHostID int64 `xorm:"UNIQUE(federation_repo_mapping) NOT NULL"`
|
FederationHostID int64 `xorm:"UNIQUE(federation_repo_mapping) NOT NULL"`
|
||||||
|
ExternalOwner string `xorm:"TEXT UNIQUE(federation_repo_mapping) NOT NULL"`
|
||||||
|
ExternalRepoName string `xorm:"TEXT UNIQUE(federation_repo_mapping) NOT NULL"`
|
||||||
Uri string
|
Uri string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFollowingRepo(repoID int64, externalID string, federationHostID int64, uri string) (FollowingRepo, error) {
|
func NewFollowingRepo(repoID int64, externalID string, federationHostID int64, externalOwner string, externalRepoName string, uri string) (FollowingRepo, error) {
|
||||||
result := FollowingRepo{
|
result := FollowingRepo{
|
||||||
RepoID: repoID,
|
RepoID: repoID,
|
||||||
ExternalID: externalID,
|
ExternalID: externalID,
|
||||||
FederationHostID: federationHostID,
|
FederationHostID: federationHostID,
|
||||||
|
ExternalOwner: externalOwner,
|
||||||
|
ExternalRepoName: externalRepoName,
|
||||||
Uri: uri,
|
Uri: uri,
|
||||||
}
|
}
|
||||||
if valid, err := validation.IsValid(result); !valid {
|
if valid, err := validation.IsValid(result); !valid {
|
||||||
|
@ -35,6 +39,8 @@ func (user FollowingRepo) Validate() []string {
|
||||||
result = append(result, validation.ValidateNotEmpty(user.RepoID, "UserID")...)
|
result = append(result, validation.ValidateNotEmpty(user.RepoID, "UserID")...)
|
||||||
result = append(result, validation.ValidateNotEmpty(user.ExternalID, "ExternalID")...)
|
result = append(result, validation.ValidateNotEmpty(user.ExternalID, "ExternalID")...)
|
||||||
result = append(result, validation.ValidateNotEmpty(user.FederationHostID, "FederationHostID")...)
|
result = append(result, validation.ValidateNotEmpty(user.FederationHostID, "FederationHostID")...)
|
||||||
|
result = append(result, validation.ValidateNotEmpty(user.ExternalOwner, "ExternalOwner")...)
|
||||||
|
result = append(result, validation.ValidateNotEmpty(user.ExternalRepoName, "ExternalRepoName")...)
|
||||||
result = append(result, validation.ValidateNotEmpty(user.Uri, "Uri")...)
|
result = append(result, validation.ValidateNotEmpty(user.Uri, "Uri")...)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -40,7 +41,7 @@ func ProcessLikeActivity(ctx context.Context, form any, repositoryID int64) (int
|
||||||
// parse actorID (person)
|
// parse actorID (person)
|
||||||
actorURI := activity.Actor.GetID().String()
|
actorURI := activity.Actor.GetID().String()
|
||||||
log.Info("actorURI was: %v", actorURI)
|
log.Info("actorURI was: %v", actorURI)
|
||||||
federationHost, err := GetFederationHostForUri(ctx, actorURI)
|
federationHost, err := GetFederationHostFromUri(ctx, actorURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, "Wrong FederationHost", err
|
return http.StatusInternalServerError, "Wrong FederationHost", err
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,7 @@ func CreateFederationHostFromAP(ctx context.Context, actorID forgefed.ActorID) (
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetFederationHostForUri(ctx context.Context, actorURI string) (*forgefed.FederationHost, error) {
|
func GetFederationHostFromUri(ctx context.Context, actorURI string) (*forgefed.FederationHost, error) {
|
||||||
// parse actorID (person)
|
// parse actorID (person)
|
||||||
log.Info("Input was: %v", actorURI)
|
log.Info("Input was: %v", actorURI)
|
||||||
rawActorID, err := forgefed.NewActorID(actorURI)
|
rawActorID, err := forgefed.NewActorID(actorURI)
|
||||||
|
@ -213,19 +214,91 @@ func CreateUserFromAP(ctx context.Context, personID forgefed.PersonID, federatio
|
||||||
return &newUser, &federatedUser, nil
|
return &newUser, &federatedUser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This needs probably an own struct/value object
|
||||||
|
// ====================================================
|
||||||
|
func GetRepoOwnerAndNameFromRepoUri(uri string) (string, string, error) {
|
||||||
|
path, err := getUriPathFromRepoUri(uri)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
pathSplit := strings.Split(path, "/")
|
||||||
|
|
||||||
|
return pathSplit[0], pathSplit[1], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRepoAPIUriFromRepoUri(uri string) (string, error) {
|
||||||
|
path, err := getUriPathFromRepoUri(uri)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedUri, err := url.ParseRequestURI(uri)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
parsedUri.Path = fmt.Sprintf("%v/%v", "api/v1/repos", path)
|
||||||
|
|
||||||
|
return parsedUri.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUriPathFromRepoUri(uri string) (string, error) {
|
||||||
|
if !IsValidRepoUri(uri) {
|
||||||
|
return "", errors.New("malformed repository uri")
|
||||||
|
}
|
||||||
|
parsedUri, err := url.ParseRequestURI(uri)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
path := strings.TrimPrefix(parsedUri.Path, "/")
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This belongs into some value object
|
||||||
|
func IsValidRepoUri(uri string) bool {
|
||||||
|
parsedUri, err := url.ParseRequestURI(uri)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
path := strings.TrimPrefix(parsedUri.Path, "/")
|
||||||
|
pathSplit := strings.Split(path, "/")
|
||||||
|
if len(pathSplit) != 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, part := range pathSplit {
|
||||||
|
if strings.TrimSpace(part) == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
// Create or update a list of FollowingRepo structs
|
// Create or update a list of FollowingRepo structs
|
||||||
func StoreFollowingRepoList(ctx context.Context, localRepoId int64, followingRepoList []string) (int, string, error) {
|
func StoreFollowingRepoList(ctx context.Context, localRepoId int64, followingRepoList []string) (int, string, error) {
|
||||||
followingRepos := make([]*repo.FollowingRepo, 0, len(followingRepoList))
|
followingRepos := make([]*repo.FollowingRepo, 0, len(followingRepoList))
|
||||||
for _, uri := range followingRepoList {
|
for _, uri := range followingRepoList {
|
||||||
federationHost, err := GetFederationHostForUri(ctx, uri)
|
owner, repoName, err := GetRepoOwnerAndNameFromRepoUri(uri)
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusBadRequest, "Malformed Repository URI", err
|
||||||
|
}
|
||||||
|
repoApiUri, err := GetRepoAPIUriFromRepoUri(uri)
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusBadRequest, "Malformed Repository URI", err
|
||||||
|
}
|
||||||
|
log.Info("RepoApiUri: %q", repoApiUri)
|
||||||
|
|
||||||
|
// TODO: derive host from repoApiUri or derive APAPI URI from repoApiUri
|
||||||
|
federationHost, err := GetFederationHostFromUri(ctx, repoApiUri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, "Wrong FederationHost", err
|
return http.StatusInternalServerError, "Wrong FederationHost", err
|
||||||
}
|
}
|
||||||
followingRepoID, err := forgefed.NewRepositoryID(uri, string(federationHost.NodeInfo.Source))
|
// TODO: derive id from repoApiUri
|
||||||
|
followingRepoID, err := forgefed.NewRepositoryID(repoApiUri, string(federationHost.NodeInfo.Source))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusNotAcceptable, "Invalid federated repo", err
|
return http.StatusNotAcceptable, "Invalid federated repo", err
|
||||||
}
|
}
|
||||||
followingRepo, err := repo.NewFollowingRepo(localRepoId, followingRepoID.ID, federationHost.ID, uri)
|
followingRepo, err := repo.NewFollowingRepo(localRepoId, followingRepoID.ID, federationHost.ID, owner, repoName, uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusNotAcceptable, "Invalid federated repo", err
|
return http.StatusNotAcceptable, "Invalid federated repo", err
|
||||||
}
|
}
|
||||||
|
|
39
services/federation/federation_service_test.go
Normal file
39
services/federation/federation_service_test.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package federation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_IsValidRepoUri(t *testing.T) {
|
||||||
|
validUri := "http://localhost:3000/me/test"
|
||||||
|
invalidUri := "http://localhost:3000/me/test/foo"
|
||||||
|
assert.True(t, IsValidRepoUri(validUri))
|
||||||
|
assert.False(t, IsValidRepoUri(invalidUri))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_GetRepoAPIUriFromRepoUri(t *testing.T) {
|
||||||
|
uri := "http://localhost:3000/me/test"
|
||||||
|
expectedUri := "http://localhost:3000/api/v1/repos/me/test"
|
||||||
|
|
||||||
|
res, err := GetRepoAPIUriFromRepoUri(uri)
|
||||||
|
assert.ErrorIs(t, err, nil)
|
||||||
|
assert.Equal(t, expectedUri, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_GetRepoOwnerAndNameFromRepoUri(t *testing.T) {
|
||||||
|
validUri := "http://localhost:3000/me/test"
|
||||||
|
invalidUri := "http://localhost:3000/me/test/foo"
|
||||||
|
|
||||||
|
owner, name, err := GetRepoOwnerAndNameFromRepoUri(validUri)
|
||||||
|
assert.ErrorIs(t, err, nil)
|
||||||
|
assert.Equal(t, "me", owner)
|
||||||
|
assert.Equal(t, "test", name)
|
||||||
|
|
||||||
|
_, _, err = GetRepoOwnerAndNameFromRepoUri(invalidUri)
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
Loading…
Reference in a new issue