mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-08-06 02:15:20 +02:00
feat(activitiypub): enable HTTP signatures on all ActivityPub endpoints (#7035)
- Set the right keyID and use the right signing keys for outgoing requests. - Verify the HTTP signature of all incoming requests, except for the server actor. - Caches keys of incoming requests for users and servers actors. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7035 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: famfo <famfo@famfo.xyz> Co-committed-by: famfo <famfo@famfo.xyz>
This commit is contained in:
parent
ba5b157f7e
commit
77b0275572
22 changed files with 681 additions and 122 deletions
|
@ -98,39 +98,47 @@ func ProcessLikeActivity(ctx context.Context, form any, repositoryID int64) (int
|
|||
}
|
||||
|
||||
func CreateFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forgefed.FederationHost, error) {
|
||||
actionsUser := user.NewActionsUser()
|
||||
actionsUser := user.NewAPServerActor()
|
||||
clientFactory, err := activitypub.GetClientFactory(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := clientFactory.WithKeys(ctx, actionsUser, "no idea where to get key material.")
|
||||
|
||||
client, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.APActorKeyID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := client.GetBody(actorID.AsWellKnownNodeInfoURI())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeInfoWellKnown, err := forgefed.NewNodeInfoWellKnown(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err = client.GetBody(nodeInfoWellKnown.Href)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeInfo, err := forgefed.NewNodeInfo(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := forgefed.NewFederationHost(nodeInfo, actorID.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = forgefed.CreateFederationHost(ctx, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
|
@ -155,18 +163,18 @@ func GetFederationHostForURI(ctx context.Context, actorURI string) (*forgefed.Fe
|
|||
}
|
||||
|
||||
func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) {
|
||||
// ToDo: Do we get a publicKeyId from server, repo or owner or repo?
|
||||
actionsUser := user.NewActionsUser()
|
||||
actionsUser := user.NewAPServerActor()
|
||||
clientFactory, err := activitypub.GetClientFactory(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
client, err := clientFactory.WithKeys(ctx, actionsUser, "no idea where to get key material.")
|
||||
|
||||
apClient, err := clientFactory.WithKeys(ctx, actionsUser, actionsUser.APActorKeyID())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
body, err := client.GetBody(personID.AsURI())
|
||||
body, err := apClient.GetBody(personID.AsURI())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -176,26 +184,32 @@ func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostI
|
|||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if res, err := validation.IsValid(person); !res {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
log.Info("Fetched valid person:%q", person)
|
||||
|
||||
localFqdn, err := url.ParseRequestURI(setting.AppURL)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
email := fmt.Sprintf("f%v@%v", uuid.New().String(), localFqdn.Hostname())
|
||||
loginName := personID.AsLoginName()
|
||||
name := fmt.Sprintf("%v%v", person.PreferredUsername.String(), personID.HostSuffix())
|
||||
fullName := person.Name.String()
|
||||
|
||||
if len(person.Name) == 0 {
|
||||
fullName = name
|
||||
}
|
||||
|
||||
password, err := password.Generate(32)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
newUser := user.User{
|
||||
LowerName: strings.ToLower(name),
|
||||
Name: name,
|
||||
|
@ -209,16 +223,18 @@ func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostI
|
|||
IsAdmin: false,
|
||||
NormalizedFederatedURI: personID.AsURI(),
|
||||
}
|
||||
|
||||
federatedUser := user.FederatedUser{
|
||||
ExternalID: personID.ID,
|
||||
FederationHostID: federationHostID,
|
||||
}
|
||||
|
||||
err = user.CreateFederatedUser(ctx, &newUser, &federatedUser)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
log.Info("Created federatedUser:%q", federatedUser)
|
||||
|
||||
log.Info("Created federatedUser:%q", federatedUser)
|
||||
return &newUser, &federatedUser, nil
|
||||
}
|
||||
|
||||
|
@ -274,7 +290,8 @@ func SendLikeActivities(ctx context.Context, doer user.User, repoID int64) error
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apclient, err := apclientFactory.WithKeys(ctx, &doer, doer.APActorID())
|
||||
|
||||
apclient, err := apclientFactory.WithKeys(ctx, &doer, doer.APActorKeyID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -285,7 +302,7 @@ func SendLikeActivities(ctx context.Context, doer user.User, repoID int64) error
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = apclient.Post(json, fmt.Sprintf("%v/inbox/", activity.Object))
|
||||
_, err = apclient.Post(json, fmt.Sprintf("%s/inbox", activity.Object))
|
||||
if err != nil {
|
||||
log.Error("error %v while sending activity: %q", err, activity)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue