From 66bc7a9a0c4650727b2d8fc36619c028511f21de Mon Sep 17 00:00:00 2001 From: Michael Jerger Date: Thu, 8 Feb 2024 11:09:55 +0100 Subject: [PATCH] Search federatedUser instead of loginName --- models/forgefed/federationhost_repository.go | 1 - models/user/user.go | 11 ++++ models/user/user_repository.go | 26 +++++++++ routers/api/v1/activitypub/repository.go | 60 +++----------------- 4 files changed, 46 insertions(+), 52 deletions(-) diff --git a/models/forgefed/federationhost_repository.go b/models/forgefed/federationhost_repository.go index 37987d5720..4adb7a5c13 100644 --- a/models/forgefed/federationhost_repository.go +++ b/models/forgefed/federationhost_repository.go @@ -32,7 +32,6 @@ func GetFederationHost(ctx context.Context, ID int64) (*FederationHost, error) { func FindFederationHostByFqdn(ctx context.Context, fqdn string) (*FederationHost, error) { host := new(FederationHost) - // TODO: use parameter with toLower has, err := db.GetEngine(ctx).Where("host_fqdn=?", strings.ToLower(fqdn)).Get(host) if err != nil { return nil, err diff --git a/models/user/user.go b/models/user/user.go index 71f823dc31..5490bd4cf1 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -811,6 +811,17 @@ func ValidateUser(u *User, cols ...string) error { return nil } +func (user User) Validate() []string { + var result []string + if err := ValidateUser(&user); err != nil { + result = append(result, err.Error()) + } + if err := ValidateEmail(user.Email); err != nil { + result = append(result, err.Error()) + } + return result +} + // UpdateUserCols update user according special columns func UpdateUserCols(ctx context.Context, u *User, cols ...string) error { if err := ValidateUser(u, cols...); err != nil { diff --git a/models/user/user_repository.go b/models/user/user_repository.go index e6d625aae5..f4d34318fc 100644 --- a/models/user/user_repository.go +++ b/models/user/user_repository.go @@ -22,3 +22,29 @@ func CreateFederationUser(ctx context.Context, user *FederatedUser) error { _, err := db.GetEngine(ctx).Insert(user) return err } + +func FindFederatedUser(ctx context.Context, externalID string, + federationHostID int64) (*User, *FederatedUser, error) { + federatedUser := new(FederatedUser) + user := new(User) + has, err := db.GetEngine(ctx).Where("external_id=? and federation_host_id=?", externalID, federationHostID).Get(federatedUser) + if err != nil { + return nil, nil, err + } else if !has { + return nil, nil, nil + } + has, err = db.GetEngine(ctx).ID(federatedUser.UserID).Get(user) + if err != nil { + return nil, nil, err + } else if !has { + return nil, nil, fmt.Errorf("User %v for federated user is missing.", federatedUser.UserID) + } + + if res, err := validation.IsValid(*user); !res { + return nil, nil, fmt.Errorf("FederatedUser is not valid: %v", err) + } + if res, err := validation.IsValid(*federatedUser); !res { + return nil, nil, fmt.Errorf("FederatedUser is not valid: %v", err) + } + return user, federatedUser, nil +} diff --git a/routers/api/v1/activitypub/repository.go b/routers/api/v1/activitypub/repository.go index e7052625f5..ddfcab7151 100644 --- a/routers/api/v1/activitypub/repository.go +++ b/routers/api/v1/activitypub/repository.go @@ -8,7 +8,6 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/forgefed" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -16,7 +15,6 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" @@ -74,8 +72,6 @@ func RepositoryInbox(ctx *context.APIContext) { // "204": // "$ref": "#/responses/empty" - var user *user_model.User - repository := ctx.Repo.Repository log.Info("RepositoryInbox: repo: %v", repository) @@ -137,37 +133,21 @@ func RepositoryInbox(ctx *context.APIContext) { log.Info("RepositoryInbox: remoteStargazer: %v", actorAsLoginID) // Check if user already exists - // TODO: search for federation user instead - // users, _, err := SearchFederatedUser(actorID.ID, federationHost.ID) - users, err := SearchUsersByLoginName(actorAsLoginID) + user, _, err := user_model.FindFederatedUser(ctx, actorID.ID, federationHost.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "RepositoryInbox: Searching for user failed", err) return } - log.Info("RepositoryInbox: local found users: %v", len(users)) - - switch len(users) { - case 0: - { - user, err = createUserFromAP(ctx, actorID, federationHost.ID) - if err != nil { - ctx.Error(http.StatusInternalServerError, - "RepositoryInbox: Creating federated user failed", err) - return - } - log.Info("RepositoryInbox: created user from ap: %v", user) - } - case 1: - { - user = users[0] - log.Info("RepositoryInbox: found user: %v", user) - } - default: - { - ctx.Error(http.StatusInternalServerError, "RepositoryInbox", - fmt.Errorf(" more than one matches for federated users")) + if user != nil { + log.Info("RepositoryInbox: found user: %v", user) + } else { + user, err = createUserFromAP(ctx, actorID, federationHost.ID) + if err != nil { + ctx.Error(http.StatusInternalServerError, + "RepositoryInbox: Creating federated user failed", err) return } + log.Info("RepositoryInbox: created user from ap: %v", user) } // execute the activity if the repo was not stared already @@ -189,28 +169,6 @@ func RepositoryInbox(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } -// TODO: Move this to model.user.search ? or to model.user.externalLoginUser ? -func SearchUsersByLoginName(loginName string) ([]*user_model.User, error) { - actionsUser := user_model.NewActionsUser() - actionsUser.IsAdmin = true - - options := &user_model.SearchUserOptions{ - LoginName: loginName, - Actor: actionsUser, - Type: user_model.UserTypeRemoteUser, - OrderBy: db.SearchOrderByAlphabetically, - ListOptions: db.ListOptions{PageSize: 1}, - IsActive: util.OptionalBoolFalse, - IncludeReserved: true, - } - users, _, err := user_model.SearchUsers(db.DefaultContext, options) - if err != nil { - return []*user_model.User{}, fmt.Errorf("search failed: %v", err) - } - - return users, nil -} - func createFederationHost(ctx *context.APIContext, actorID forgefed.ActorID) (forgefed.FederationHost, error) { actionsUser := user_model.NewActionsUser() client, err := api.NewClient(ctx, actionsUser, "no idea where to get key material.")