func()

in internal/service/user_external_login/user_external_login_service.go [92:181]


func (us *UserExternalLoginService) ExternalLogin(
	ctx context.Context, externalUserInfo *schema.ExternalLoginUserInfoCache) (
	resp *schema.UserExternalLoginResp, err error) {
	if len(externalUserInfo.ExternalID) == 0 {
		return &schema.UserExternalLoginResp{
			ErrTitle: translator.Tr(handler.GetLangByCtx(ctx), reason.UserAccessDenied),
			ErrMsg:   translator.Tr(handler.GetLangByCtx(ctx), reason.UserExternalLoginMissingUserID),
		}, nil
	}

	oldExternalLoginUserInfo, exist, err := us.userExternalLoginRepo.GetByExternalID(ctx,
		externalUserInfo.Provider, externalUserInfo.ExternalID)
	if err != nil {
		return nil, err
	}
	if exist {
		// if user is already a member, login directly
		oldUserInfo, exist, err := us.userRepo.GetByUserID(ctx, oldExternalLoginUserInfo.UserID)
		if err != nil {
			return nil, err
		}
		if exist && oldUserInfo.Status != entity.UserStatusDeleted {
			if err := us.userRepo.UpdateLastLoginDate(ctx, oldUserInfo.ID); err != nil {
				log.Errorf("update user last login date failed: %v", err)
			}
			newMailStatus, err := us.activeUser(ctx, oldUserInfo, externalUserInfo)
			if err != nil {
				log.Error(err)
			}
			accessToken, _, err := us.userCommonService.CacheLoginUserInfo(
				ctx, oldUserInfo.ID, newMailStatus, oldUserInfo.Status, oldExternalLoginUserInfo.ExternalID)
			return &schema.UserExternalLoginResp{AccessToken: accessToken}, err
		}
	}

	// cache external user info, waiting for user enter email address.
	if len(externalUserInfo.Email) == 0 {
		bindingKey := token.GenerateToken()
		err = us.userExternalLoginRepo.SetCacheUserExternalLoginInfo(ctx, bindingKey, externalUserInfo)
		if err != nil {
			return nil, err
		}
		return &schema.UserExternalLoginResp{BindingKey: bindingKey}, nil
	}

	// check whether site allow register or not
	siteInfo, err := us.siteInfoCommonService.GetSiteLogin(ctx)
	if err != nil {
		return nil, err
	}
	if !checker.EmailInAllowEmailDomain(externalUserInfo.Email, siteInfo.AllowEmailDomains) {
		log.Debugf("email domain not allowed: %s", externalUserInfo.Email)
		return &schema.UserExternalLoginResp{
			ErrTitle: translator.Tr(handler.GetLangByCtx(ctx), reason.UserAccessDenied),
			ErrMsg:   translator.Tr(handler.GetLangByCtx(ctx), reason.EmailIllegalDomainError),
		}, nil
	}

	oldUserInfo, exist, err := us.userRepo.GetByEmail(ctx, externalUserInfo.Email)
	if err != nil {
		return nil, err
	}
	// if user is not a member, register a new user
	if !exist {
		oldUserInfo, err = us.registerNewUser(ctx, externalUserInfo)
		if err != nil {
			return nil, err
		}
	}
	// bind external user info to user
	err = us.bindOldUser(ctx, externalUserInfo, oldUserInfo)
	if err != nil {
		return nil, err
	}

	// If user login with external account and email is exist, active user directly.
	newMailStatus, err := us.activeUser(ctx, oldUserInfo, externalUserInfo)
	if err != nil {
		log.Error(err)
	}

	// set default user notification config for external user
	if err := us.userNotificationConfigService.SetDefaultUserNotificationConfig(ctx, []string{oldUserInfo.ID}); err != nil {
		log.Errorf("set default user notification config failed, err: %v", err)
	}

	accessToken, _, err := us.userCommonService.CacheLoginUserInfo(
		ctx, oldUserInfo.ID, newMailStatus, oldUserInfo.Status, oldExternalLoginUserInfo.ExternalID)
	return &schema.UserExternalLoginResp{AccessToken: accessToken}, err
}