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