code.gitea.io/gitea@v1.22.3/services/externalaccount/user.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package externalaccount
     5  
     6  import (
     7  	"context"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"code.gitea.io/gitea/models/auth"
    12  	issues_model "code.gitea.io/gitea/models/issues"
    13  	repo_model "code.gitea.io/gitea/models/repo"
    14  	user_model "code.gitea.io/gitea/models/user"
    15  	"code.gitea.io/gitea/modules/structs"
    16  
    17  	"github.com/markbates/goth"
    18  )
    19  
    20  func toExternalLoginUser(ctx context.Context, user *user_model.User, gothUser goth.User) (*user_model.ExternalLoginUser, error) {
    21  	authSource, err := auth.GetActiveOAuth2SourceByName(ctx, gothUser.Provider)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	return &user_model.ExternalLoginUser{
    26  		ExternalID:        gothUser.UserID,
    27  		UserID:            user.ID,
    28  		LoginSourceID:     authSource.ID,
    29  		RawData:           gothUser.RawData,
    30  		Provider:          gothUser.Provider,
    31  		Email:             gothUser.Email,
    32  		Name:              gothUser.Name,
    33  		FirstName:         gothUser.FirstName,
    34  		LastName:          gothUser.LastName,
    35  		NickName:          gothUser.NickName,
    36  		Description:       gothUser.Description,
    37  		AvatarURL:         gothUser.AvatarURL,
    38  		Location:          gothUser.Location,
    39  		AccessToken:       gothUser.AccessToken,
    40  		AccessTokenSecret: gothUser.AccessTokenSecret,
    41  		RefreshToken:      gothUser.RefreshToken,
    42  		ExpiresAt:         gothUser.ExpiresAt,
    43  	}, nil
    44  }
    45  
    46  // LinkAccountToUser link the gothUser to the user
    47  func LinkAccountToUser(ctx context.Context, user *user_model.User, gothUser goth.User) error {
    48  	externalLoginUser, err := toExternalLoginUser(ctx, user, gothUser)
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	if err := user_model.LinkExternalToUser(ctx, user, externalLoginUser); err != nil {
    54  		return err
    55  	}
    56  
    57  	externalID := externalLoginUser.ExternalID
    58  
    59  	var tp structs.GitServiceType
    60  	for _, s := range structs.SupportedFullGitService {
    61  		if strings.EqualFold(s.Name(), gothUser.Provider) {
    62  			tp = s
    63  			break
    64  		}
    65  	}
    66  
    67  	if tp.Name() != "" {
    68  		return UpdateMigrationsByType(ctx, tp, externalID, user.ID)
    69  	}
    70  
    71  	return nil
    72  }
    73  
    74  // UpdateExternalUser updates external user's information
    75  func UpdateExternalUser(ctx context.Context, user *user_model.User, gothUser goth.User) error {
    76  	externalLoginUser, err := toExternalLoginUser(ctx, user, gothUser)
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	return user_model.UpdateExternalUserByExternalID(ctx, externalLoginUser)
    82  }
    83  
    84  // UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID
    85  func UpdateMigrationsByType(ctx context.Context, tp structs.GitServiceType, externalUserID string, userID int64) error {
    86  	// Skip update if externalUserID is not a valid numeric ID or exceeds int64
    87  	if _, err := strconv.ParseInt(externalUserID, 10, 64); err != nil {
    88  		return nil
    89  	}
    90  
    91  	if err := issues_model.UpdateIssuesMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
    92  		return err
    93  	}
    94  
    95  	if err := issues_model.UpdateCommentsMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
    96  		return err
    97  	}
    98  
    99  	if err := repo_model.UpdateReleasesMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
   100  		return err
   101  	}
   102  
   103  	if err := issues_model.UpdateReactionsMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
   104  		return err
   105  	}
   106  	return issues_model.UpdateReviewsMigrationsByType(ctx, tp, externalUserID, userID)
   107  }