forgejo/services/externalaccount/user.go
Gusted 7f8f9b878f
fix: Revert "allow synchronizing user status from OAuth2 login providers (#31572)"
This commit has a fundamental flaw, in order to syncronize if external
users are still active the commit checks if the refresh token is
accepted by the OAuth provider, if that is not the case it sees that as
the user is disabled and sets the is active field to `false` to signal
that. Because it might be possible (this commit makes this a highly
likelyhood) that the OAuth provider still recognizes this user the
commit introduces code to allow users to re-active themselves via the
oauth flow if they were disabled because of this. However this code
makes no distinction in why the user was disabled and always re-actives
the user.

Thus the reactivation via the OAuth flow allows users to bypass the
manually activation setting (`[service].REGISTER_MANUAL_CONFIRM`) or if
the admin for other reasons disabled the user.

This reverts commit 21fdd28f08.
2024-12-12 05:59:06 +01:00

107 lines
3.3 KiB
Go

// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package externalaccount
import (
"context"
"strconv"
"strings"
"code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/structs"
"github.com/markbates/goth"
)
func toExternalLoginUser(ctx context.Context, user *user_model.User, gothUser goth.User) (*user_model.ExternalLoginUser, error) {
authSource, err := auth.GetActiveOAuth2SourceByName(ctx, gothUser.Provider)
if err != nil {
return nil, err
}
return &user_model.ExternalLoginUser{
ExternalID: gothUser.UserID,
UserID: user.ID,
LoginSourceID: authSource.ID,
RawData: gothUser.RawData,
Provider: gothUser.Provider,
Email: gothUser.Email,
Name: gothUser.Name,
FirstName: gothUser.FirstName,
LastName: gothUser.LastName,
NickName: gothUser.NickName,
Description: gothUser.Description,
AvatarURL: gothUser.AvatarURL,
Location: gothUser.Location,
AccessToken: gothUser.AccessToken,
AccessTokenSecret: gothUser.AccessTokenSecret,
RefreshToken: gothUser.RefreshToken,
ExpiresAt: gothUser.ExpiresAt,
}, nil
}
// LinkAccountToUser link the gothUser to the user
func LinkAccountToUser(ctx context.Context, user *user_model.User, gothUser goth.User) error {
externalLoginUser, err := toExternalLoginUser(ctx, user, gothUser)
if err != nil {
return err
}
if err := user_model.LinkExternalToUser(ctx, user, externalLoginUser); err != nil {
return err
}
externalID := externalLoginUser.ExternalID
var tp structs.GitServiceType
for _, s := range structs.SupportedFullGitService {
if strings.EqualFold(s.Name(), gothUser.Provider) {
tp = s
break
}
}
if tp.Name() != "" {
return UpdateMigrationsByType(ctx, tp, externalID, user.ID)
}
return nil
}
// UpdateExternalUser updates external user's information
func UpdateExternalUser(ctx context.Context, user *user_model.User, gothUser goth.User) error {
externalLoginUser, err := toExternalLoginUser(ctx, user, gothUser)
if err != nil {
return err
}
return user_model.UpdateExternalUserByExternalID(ctx, externalLoginUser)
}
// UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID
func UpdateMigrationsByType(ctx context.Context, tp structs.GitServiceType, externalUserID string, userID int64) error {
// Skip update if externalUserID is not a valid numeric ID or exceeds int64
if _, err := strconv.ParseInt(externalUserID, 10, 64); err != nil {
return nil
}
if err := issues_model.UpdateIssuesMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
return err
}
if err := issues_model.UpdateCommentsMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
return err
}
if err := repo_model.UpdateReleasesMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
return err
}
if err := issues_model.UpdateReactionsMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
return err
}
return issues_model.UpdateReviewsMigrationsByType(ctx, tp, externalUserID, userID)
}