mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-04-20 03:11:35 +02:00
further steps
This commit is contained in:
parent
bcf32a0925
commit
1beb749355
9 changed files with 112 additions and 37 deletions
|
@ -18,16 +18,20 @@ type FederationHost struct {
|
|||
ID int64 `xorm:"pk autoincr"`
|
||||
HostFqdn string `xorm:"host_fqdn UNIQUE INDEX VARCHAR(255) NOT NULL"`
|
||||
NodeInfo NodeInfo `xorm:"extends NOT NULL"`
|
||||
HostPort uint16 `xorm:"NOT NULL"`
|
||||
HostSchema string `xorm:"NOT NULL"`
|
||||
LatestActivity time.Time `xorm:"NOT NULL"`
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||
}
|
||||
|
||||
// Factory function for FederationHost. Created struct is asserted to be valid.
|
||||
func NewFederationHost(nodeInfo NodeInfo, hostFqdn string) (FederationHost, error) {
|
||||
func NewFederationHost(hostFqdn string, nodeInfo NodeInfo, port uint16, schema string) (FederationHost, error) {
|
||||
result := FederationHost{
|
||||
HostFqdn: strings.ToLower(hostFqdn),
|
||||
NodeInfo: nodeInfo,
|
||||
HostFqdn: strings.ToLower(hostFqdn),
|
||||
NodeInfo: nodeInfo,
|
||||
HostPort: port,
|
||||
HostSchema: schema,
|
||||
}
|
||||
if valid, err := validation.IsValid(result); !valid {
|
||||
return FederationHost{}, err
|
||||
|
@ -36,10 +40,13 @@ func NewFederationHost(nodeInfo NodeInfo, hostFqdn string) (FederationHost, erro
|
|||
}
|
||||
|
||||
// Validate collects error strings in a slice and returns this
|
||||
// ToDo validate port>0, schema{https|http}
|
||||
func (host FederationHost) Validate() []string {
|
||||
var result []string
|
||||
result = append(result, validation.ValidateNotEmpty(host.HostFqdn, "HostFqdn")...)
|
||||
result = append(result, validation.ValidateMaxLen(host.HostFqdn, 255, "HostFqdn")...)
|
||||
result = append(result, validation.ValidateNotEmpty(host.HostPort, "HostPort")...)
|
||||
result = append(result, validation.ValidateNotEmpty(host.HostSchema, "HostSchema")...)
|
||||
result = append(result, host.NodeInfo.Validate()...)
|
||||
if host.HostFqdn != strings.ToLower(host.HostFqdn) {
|
||||
result = append(result, fmt.Sprintf("HostFqdn has to be lower case but was: %v", host.HostFqdn))
|
||||
|
|
|
@ -71,7 +71,7 @@ var migrations = []*Migration{
|
|||
// v15 -> v16
|
||||
NewMigration("Create the `federated_user` table", CreateFederatedUserTable),
|
||||
// v16 -> v17
|
||||
NewMigration("Add `normalized_federated_uri` column to `user` table", AddNormalizedOriginalUrlToUser),
|
||||
NewMigration("Add `normalized_federated_uri` column to `user` table", AddFederatedURIToUser),
|
||||
// v17 -> v18
|
||||
NewMigration("Create the `following_repo` table", CreateFollowingRepoTable),
|
||||
// v18 -> v19
|
||||
|
|
|
@ -5,10 +5,10 @@ package forgejo_migrations //nolint:revive
|
|||
|
||||
import "xorm.io/xorm"
|
||||
|
||||
func AddNormalizedOriginalUrlToUser(x *xorm.Engine) error {
|
||||
func AddFederatedURIToUser(x *xorm.Engine) error {
|
||||
type User struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
NormalizedOriginalUrl string
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
NormalizedFederatedURI string
|
||||
}
|
||||
return x.Sync(&User{})
|
||||
}
|
||||
|
|
|
@ -12,8 +12,6 @@ type FederatedUser struct {
|
|||
UserID int64 `xorm:"NOT NULL"`
|
||||
ExternalID string `xorm:"UNIQUE(federation_user_mapping) NOT NULL"`
|
||||
FederationHostID int64 `xorm:"UNIQUE(federation_user_mapping) NOT NULL"`
|
||||
InboxURL *string
|
||||
ActorURL *string
|
||||
NormalizedOriginalUrl string
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ package forgefed
|
|||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
|
@ -17,10 +18,10 @@ import (
|
|||
type ActorID struct {
|
||||
ID string
|
||||
Source string
|
||||
Schema string
|
||||
HostSchema string
|
||||
Path string
|
||||
Host string
|
||||
Port string
|
||||
HostPort uint16
|
||||
UnvalidatedInput string
|
||||
}
|
||||
|
||||
|
@ -40,10 +41,10 @@ func NewActorID(uri string) (ActorID, error) {
|
|||
|
||||
func (id ActorID) AsURI() string {
|
||||
var result string
|
||||
if id.Port == "" {
|
||||
result = fmt.Sprintf("%s://%s/%s/%s", id.Schema, id.Host, id.Path, id.ID)
|
||||
if id.HostPort == 0 {
|
||||
result = fmt.Sprintf("%s://%s/%s/%s", id.HostSchema, id.Host, id.Path, id.ID)
|
||||
} else {
|
||||
result = fmt.Sprintf("%s://%s:%s/%s/%s", id.Schema, id.Host, id.Port, id.Path, id.ID)
|
||||
result = fmt.Sprintf("%s://%s:%d/%s/%s", id.HostSchema, id.Host, id.HostPort, id.Path, id.ID)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -51,9 +52,11 @@ func (id ActorID) AsURI() string {
|
|||
func (id ActorID) Validate() []string {
|
||||
var result []string
|
||||
result = append(result, validation.ValidateNotEmpty(id.ID, "userId")...)
|
||||
result = append(result, validation.ValidateNotEmpty(id.Schema, "schema")...)
|
||||
result = append(result, validation.ValidateNotEmpty(id.HostSchema, "schema")...)
|
||||
result = append(result, validation.ValidateNotEmpty(id.Path, "path")...)
|
||||
result = append(result, validation.ValidateNotEmpty(id.Host, "host")...)
|
||||
//ToDo Port should be >0
|
||||
result = append(result, validation.ValidateNotEmpty(id.HostPort, "HostPort")...)
|
||||
result = append(result, validation.ValidateNotEmpty(id.UnvalidatedInput, "unvalidatedInput")...)
|
||||
|
||||
if id.UnvalidatedInput != id.AsURI() {
|
||||
|
@ -183,10 +186,40 @@ func newActorID(uri string) (ActorID, error) {
|
|||
|
||||
result := ActorID{}
|
||||
result.ID = id
|
||||
result.Schema = validatedURI.Scheme
|
||||
result.HostSchema = validatedURI.Scheme
|
||||
result.Host = validatedURI.Hostname()
|
||||
result.Path = pathWithoutActorID
|
||||
result.Port = validatedURI.Port()
|
||||
//Todo correct type & cond 443|80
|
||||
numPort, err := strconv.ParseUint(validatedURI.Port(), 10, 16)
|
||||
//error
|
||||
//fmt.Printf("\nerror\n numPort= %v\n datatype: %T\n", numPort, numPort)
|
||||
//fmt.Printf("\nerror\n err= %v\n err: %T\n", err, err)
|
||||
|
||||
if err != nil {
|
||||
} else if result.HostSchema == "https" {
|
||||
numPort = 443
|
||||
} else if result.HostSchema == "http" {
|
||||
numPort = 80
|
||||
}
|
||||
/* if numPort == 0 then set no value like result = fmt.Sprintf("%s://%s/%s/%s", id.HostSchema, id.Host, id.Path, id.ID)
|
||||
if numPort == 0 && result.HostSchema == "https" {
|
||||
numPort = 443
|
||||
}
|
||||
if numPort == 0 && result.HostSchema == "http" {
|
||||
numPort = 80
|
||||
}
|
||||
*/
|
||||
if numPort == 0 && result.HostSchema == "https" {
|
||||
numPort = 443
|
||||
result.HostPort = uint16(numPort)
|
||||
//result = fmt.Sprintf("%s://%s/%s/%s", id.HostSchema, id.Host, id.Path, id.ID)
|
||||
result.UnvalidatedInput = uri
|
||||
fmt.Printf("\ninside numPort = 0: %v\n datatype: %T\n", result, result)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
result.HostPort = uint16(numPort)
|
||||
fmt.Printf("\nresult.HostPort: %v\n datatype: %T\n", result.HostPort, result.HostPort)
|
||||
result.UnvalidatedInput = uri
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
@ -18,11 +18,12 @@ func TestNewPersonId(t *testing.T) {
|
|||
expected := PersonID{}
|
||||
expected.ID = "1"
|
||||
expected.Source = "forgejo"
|
||||
expected.Schema = "https"
|
||||
expected.HostSchema = "https"
|
||||
expected.Path = "api/v1/activitypub/user-id"
|
||||
expected.Host = "an.other.host"
|
||||
expected.Port = ""
|
||||
expected.HostPort = 443
|
||||
expected.UnvalidatedInput = "https://an.other.host/api/v1/activitypub/user-id/1"
|
||||
t.Log("end at expected 443, but missing")
|
||||
sut, _ := NewPersonID("https://an.other.host/api/v1/activitypub/user-id/1", "forgejo")
|
||||
if sut != expected {
|
||||
t.Errorf("expected: %v\n but was: %v\n", expected, sut)
|
||||
|
@ -31,11 +32,42 @@ func TestNewPersonId(t *testing.T) {
|
|||
expected = PersonID{}
|
||||
expected.ID = "1"
|
||||
expected.Source = "forgejo"
|
||||
expected.Schema = "https"
|
||||
expected.HostSchema = "https"
|
||||
expected.Path = "api/v1/activitypub/user-id"
|
||||
expected.Host = "an.other.host"
|
||||
expected.Port = "443"
|
||||
expected.HostPort = 443
|
||||
expected.UnvalidatedInput = "https://an.other.host:443/api/v1/activitypub/user-id/1"
|
||||
t.Log("end at expected 443, given")
|
||||
sut, _ = NewPersonID("https://an.other.host:443/api/v1/activitypub/user-id/1", "forgejo")
|
||||
if sut != expected {
|
||||
t.Errorf("expected: %v\n but was: %v\n", expected, sut)
|
||||
}
|
||||
|
||||
//Todo doit with http:80
|
||||
expected = PersonID{}
|
||||
expected.ID = "1"
|
||||
expected.Source = "forgejo"
|
||||
expected.HostSchema = "http"
|
||||
expected.Path = "api/v1/activitypub/user-id"
|
||||
expected.Host = "an.other.host"
|
||||
expected.HostPort = 80
|
||||
expected.UnvalidatedInput = "http://an.other.host:80/api/v1/activitypub/user-id/1"
|
||||
t.Log("end at expected 80, given")
|
||||
sut, _ = NewPersonID("http://an.other.host:80/api/v1/activitypub/user-id/1", "forgejo")
|
||||
if sut != expected {
|
||||
t.Errorf("expected: %v\n but was: %v\n", expected, sut)
|
||||
}
|
||||
|
||||
//Todo HTTPS
|
||||
expected = PersonID{}
|
||||
expected.ID = "1"
|
||||
expected.Source = "forgejo"
|
||||
expected.HostSchema = "HTTPS"
|
||||
expected.Path = "api/v1/activitypub/user-id"
|
||||
expected.Host = "an.other.host"
|
||||
expected.HostPort = 443
|
||||
expected.UnvalidatedInput = "https://an.other.host:443/api/v1/activitypub/user-id/1"
|
||||
t.Log("end at expected HTTPS, given")
|
||||
sut, _ = NewPersonID("https://an.other.host:443/api/v1/activitypub/user-id/1", "forgejo")
|
||||
if sut != expected {
|
||||
t.Errorf("expected: %v\n but was: %v\n", expected, sut)
|
||||
|
@ -47,10 +79,10 @@ func TestNewRepositoryId(t *testing.T) {
|
|||
expected := RepositoryID{}
|
||||
expected.ID = "1"
|
||||
expected.Source = "forgejo"
|
||||
expected.Schema = "http"
|
||||
expected.HostSchema = "http"
|
||||
expected.Path = "api/activitypub/repository-id"
|
||||
expected.Host = "localhost"
|
||||
expected.Port = "3000"
|
||||
expected.HostPort = 3000
|
||||
expected.UnvalidatedInput = "http://localhost:3000/api/activitypub/repository-id/1"
|
||||
sut, _ := NewRepositoryID("http://localhost:3000/api/activitypub/repository-id/1", "forgejo")
|
||||
if sut != expected {
|
||||
|
@ -61,10 +93,10 @@ func TestNewRepositoryId(t *testing.T) {
|
|||
func TestActorIdValidation(t *testing.T) {
|
||||
sut := ActorID{}
|
||||
sut.Source = "forgejo"
|
||||
sut.Schema = "https"
|
||||
sut.HostSchema = "https"
|
||||
sut.Path = "api/v1/activitypub/user-id"
|
||||
sut.Host = "an.other.host"
|
||||
sut.Port = ""
|
||||
sut.HostPort = 0
|
||||
sut.UnvalidatedInput = "https://an.other.host/api/v1/activitypub/user-id/"
|
||||
if sut.Validate()[0] != "userId should not be empty" {
|
||||
t.Errorf("validation error expected but was: %v\n", sut.Validate())
|
||||
|
@ -73,10 +105,10 @@ func TestActorIdValidation(t *testing.T) {
|
|||
sut = ActorID{}
|
||||
sut.ID = "1"
|
||||
sut.Source = "forgejo"
|
||||
sut.Schema = "https"
|
||||
sut.HostSchema = "https"
|
||||
sut.Path = "api/v1/activitypub/user-id"
|
||||
sut.Host = "an.other.host"
|
||||
sut.Port = ""
|
||||
sut.HostPort = 0
|
||||
sut.UnvalidatedInput = "https://an.other.host/api/v1/activitypub/user-id/1?illegal=action"
|
||||
if sut.Validate()[0] != "not all input was parsed, \nUnvalidated Input:\"https://an.other.host/api/v1/activitypub/user-id/1?illegal=action\" \nParsed URI: \"https://an.other.host/api/v1/activitypub/user-id/1\"" {
|
||||
t.Errorf("validation error expected but was: %v\n", sut.Validate()[0])
|
||||
|
@ -87,10 +119,10 @@ func TestPersonIdValidation(t *testing.T) {
|
|||
sut := PersonID{}
|
||||
sut.ID = "1"
|
||||
sut.Source = "forgejo"
|
||||
sut.Schema = "https"
|
||||
sut.HostSchema = "https"
|
||||
sut.Path = "path"
|
||||
sut.Host = "an.other.host"
|
||||
sut.Port = ""
|
||||
sut.HostPort = 0
|
||||
sut.UnvalidatedInput = "https://an.other.host/path/1"
|
||||
|
||||
_, err := validation.IsValid(sut)
|
||||
|
@ -101,10 +133,10 @@ func TestPersonIdValidation(t *testing.T) {
|
|||
sut = PersonID{}
|
||||
sut.ID = "1"
|
||||
sut.Source = "forgejox"
|
||||
sut.Schema = "https"
|
||||
sut.HostSchema = "https"
|
||||
sut.Path = "api/v1/activitypub/user-id"
|
||||
sut.Host = "an.other.host"
|
||||
sut.Port = ""
|
||||
sut.HostPort = 0
|
||||
sut.UnvalidatedInput = "https://an.other.host/api/v1/activitypub/user-id/1"
|
||||
if sut.Validate()[0] != "Value forgejox is not contained in allowed values [forgejo gitea]" {
|
||||
t.Errorf("validation error expected but was: %v\n", sut.Validate()[0])
|
||||
|
|
|
@ -10,10 +10,10 @@ import (
|
|||
func (id ActorID) AsWellKnownNodeInfoURI() string {
|
||||
wellKnownPath := ".well-known/nodeinfo"
|
||||
var result string
|
||||
if id.Port == "" {
|
||||
result = fmt.Sprintf("%s://%s/%s", id.Schema, id.Host, wellKnownPath)
|
||||
if id.HostPort == 0 {
|
||||
result = fmt.Sprintf("%s://%s/%s", id.HostSchema, id.Host, wellKnownPath)
|
||||
} else {
|
||||
result = fmt.Sprintf("%s://%s:%s/%s", id.Schema, id.Host, id.Port, wellKnownPath)
|
||||
result = fmt.Sprintf("%s://%s:%d/%s", id.HostSchema, id.Host, id.HostPort, wellKnownPath)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -53,6 +53,10 @@ func ValidateNotEmpty(value any, name string) []string {
|
|||
if v.IsZero() {
|
||||
isValid = false
|
||||
}
|
||||
case uint16:
|
||||
if v == 0 {
|
||||
isValid = false
|
||||
}
|
||||
case int64:
|
||||
if v == 0 {
|
||||
isValid = false
|
||||
|
|
|
@ -39,6 +39,7 @@ func ProcessLikeActivity(ctx context.Context, form any, repositoryID int64) (int
|
|||
log.Info("Activity validated:%v", activity)
|
||||
|
||||
// parse actorID (person)
|
||||
// Todo: GetFederationHostForURI
|
||||
actorURI := activity.Actor.GetID().String()
|
||||
log.Info("actorURI was: %v", actorURI)
|
||||
federationHost, err := GetFederationHostForURI(ctx, actorURI)
|
||||
|
@ -123,7 +124,7 @@ func CreateFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forge
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := forgefed.NewFederationHost(nodeInfo, actorID.Host)
|
||||
result, err := forgefed.NewFederationHost(actorID.Host, nodeInfo, actorID.Port, actorID.Schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -209,8 +210,8 @@ func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostI
|
|||
IsAdmin: false,
|
||||
}
|
||||
federatedUser := user.FederatedUser{
|
||||
ExternalID: personID.ID,
|
||||
FederationHostID: federationHostID,
|
||||
ExternalID: personID.ID,
|
||||
FederationHostID: federationHostID,
|
||||
NormalizedOriginalUrl: personID.AsURI(),
|
||||
}
|
||||
err = user.CreateFederatedUser(ctx, &newUser, &federatedUser)
|
||||
|
|
Loading…
Add table
Reference in a new issue