diff --git a/modules/activitypub/authorize_interaction.go b/modules/activitypub/authorize_interaction.go new file mode 100644 index 0000000000..4b670e8223 --- /dev/null +++ b/modules/activitypub/authorize_interaction.go @@ -0,0 +1,53 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package activitypub + +import ( + "net/http" + "net/url" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/json" + + ap "github.com/go-ap/activitypub" +) + +func AuthorizeInteraction(c *context.Context) { + uri, err := url.Parse(c.Req.URL.Query().Get("uri")) + if err != nil { + c.ServerError("Could not parse URI", err) + return + } + resp, err := Fetch(uri) + if err != nil { + c.ServerError("Could not fetch remote URI", err) + return + } + + var object map[string]interface{} + err = json.Unmarshal(resp, &object) + if err != nil { + c.ServerError("Could not unmarshal response into JSON", err) + return + } + switch object["type"] { + case "Person": + var person ap.Person + person.UnmarshalJSON(resp) + err = FederatedUserNew(person) + if err != nil { + c.ServerError("Could not create new federated user", err) + return + } + /*case "organization": + // Do something idk + case "repository": + FederatedRepoNew() // TODO + case "ticket": + // TODO*/ + } + + c.Status(http.StatusOK) +} \ No newline at end of file diff --git a/modules/activitypub/iri.go b/modules/activitypub/iri.go index 92fc0add5b..70f80f0097 100644 --- a/modules/activitypub/iri.go +++ b/modules/activitypub/iri.go @@ -47,7 +47,7 @@ func personIRIToUser(ctx context.Context, personIRI ap.IRI) (*user_model.User, e return user, err } - FederatedUserNew(personIRI) + //FederatedUserNew(personIRI) return user_model.GetUserByName(ctx, name) } diff --git a/modules/activitypub/user.go b/modules/activitypub/user.go index 592649645b..66e5997145 100644 --- a/modules/activitypub/user.go +++ b/modules/activitypub/user.go @@ -5,23 +5,43 @@ package activitypub import ( + "strings" + "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/modules/setting" user_model "code.gitea.io/gitea/models/user" ap "github.com/go-ap/activitypub" ) -func FederatedUserNew(IRI ap.IRI) error { - name, err := personIRIToName(IRI) +func FederatedUserNew(person ap.Person) error { + name, err := personIRIToName(person.GetLink()) if err != nil { return err } + var email string + if person.Location != nil { + email = person.Location.GetLink().String() + } else { + email = strings.ReplaceAll(name, "@", "+") + "@" + setting.Service.NoReplyAddress + } + + var avatar string + if person.Icon != nil { + icon := person.Icon.(*ap.Image) + avatar = icon.URL.GetLink().String() + } else { + avatar = "" + } + user := &user_model.User{ Name: name, - Email: name, // TODO: change this to something else to prevent collisions with normal users, maybe fetch email using Gitea API + FullName: person.Name.String(), + Email: email, + Avatar: avatar, LoginType: auth.Federated, - Website: IRI.String(), + LoginName: person.GetLink().String(), } return user_model.CreateUser(user) } diff --git a/routers/api/v1/activitypub/person.go b/routers/api/v1/activitypub/person.go index 3bb5f4a3f1..019b084b20 100644 --- a/routers/api/v1/activitypub/person.go +++ b/routers/api/v1/activitypub/person.go @@ -58,6 +58,7 @@ func Person(ctx *context.APIContext) { } person.URL = ap.IRI(ctx.ContextUser.HTMLURL()) + person.Location = ap.IRI(ctx.ContextUser.GetEmail()) person.Icon = ap.Image{ Type: ap.ImageType, diff --git a/routers/web/web.go b/routers/web/web.go index fbece620b1..5185b1b23b 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/modules/activitypub" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/httpcache" @@ -1266,6 +1267,8 @@ func RegisterRoutes(m *web.Route) { m.Get("/new", user.NewAvailable) }, reqSignIn) + m.Get("/authorize_interaction", activitypub.AuthorizeInteraction) + if setting.API.EnableSwagger { m.Get("/swagger.v1.json", SwaggerV1Json) }