github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/services/remotecluster/invitation.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package remotecluster
     5  
     6  import (
     7  	"encoding/json"
     8  	"errors"
     9  	"fmt"
    10  
    11  	"github.com/masterhung0112/hk_server/v5/model"
    12  )
    13  
    14  // AcceptInvitation is called when accepting an invitation to connect with a remote cluster.
    15  func (rcs *Service) AcceptInvitation(invite *model.RemoteClusterInvite, name string, displayName, creatorId string, teamId string, siteURL string) (*model.RemoteCluster, error) {
    16  	rc := &model.RemoteCluster{
    17  		RemoteId:     invite.RemoteId,
    18  		RemoteTeamId: invite.RemoteTeamId,
    19  		Name:         name,
    20  		DisplayName:  displayName,
    21  		Token:        model.NewId(),
    22  		RemoteToken:  invite.Token,
    23  		SiteURL:      invite.SiteURL,
    24  		CreatorId:    creatorId,
    25  	}
    26  
    27  	rcSaved, err := rcs.server.GetStore().RemoteCluster().Save(rc)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	// confirm the invitation with the originating site
    33  	frame, err := makeConfirmFrame(rcSaved, teamId, siteURL)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  
    38  	url := fmt.Sprintf("%s/%s", rcSaved.SiteURL, ConfirmInviteURL)
    39  
    40  	resp, err := rcs.sendFrameToRemote(PingTimeout, rc, frame, url)
    41  	if err != nil {
    42  		rcs.server.GetStore().RemoteCluster().Delete(rcSaved.RemoteId)
    43  		return nil, err
    44  	}
    45  
    46  	var response Response
    47  	err = json.Unmarshal(resp, &response)
    48  	if err != nil {
    49  		rcs.server.GetStore().RemoteCluster().Delete(rcSaved.RemoteId)
    50  		return nil, fmt.Errorf("invalid response from remote server: %w", err)
    51  	}
    52  
    53  	if !response.IsSuccess() {
    54  		rcs.server.GetStore().RemoteCluster().Delete(rcSaved.RemoteId)
    55  		return nil, errors.New(response.Err)
    56  	}
    57  
    58  	// issue the first ping right away. The goroutine will exit when ping completes or PingTimeout exceeded.
    59  	go rcs.pingRemote(rcSaved)
    60  
    61  	return rcSaved, nil
    62  }
    63  
    64  func makeConfirmFrame(rc *model.RemoteCluster, teamId string, siteURL string) (*model.RemoteClusterFrame, error) {
    65  	confirm := model.RemoteClusterInvite{
    66  		RemoteId:     rc.RemoteId,
    67  		RemoteTeamId: teamId,
    68  		SiteURL:      siteURL,
    69  		Token:        rc.Token,
    70  	}
    71  	confirmRaw, err := json.Marshal(confirm)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	msg := model.NewRemoteClusterMsg(InvitationTopic, confirmRaw)
    77  
    78  	frame := &model.RemoteClusterFrame{
    79  		RemoteId: rc.RemoteId,
    80  		Msg:      msg,
    81  	}
    82  	return frame, nil
    83  }