Improves the invite mechanism for remote clusters (#31025)

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Этот коммит содержится в:
Miguel de la Cruz
2025-05-27 13:39:13 +02:00
коммит произвёл GitHub
родитель e51ea025db
Коммит fbf105f6ef
5 изменённых файлов: 36 добавлений и 11 удалений

Просмотреть файл

@@ -202,6 +202,7 @@ func (a *App) CreateRemoteClusterInvite(remoteId, siteURL, token, password strin
RemoteId: remoteId,
SiteURL: siteURL,
Token: token,
Version: 2,
}
if err := invite.IsValid(); err != nil {

Просмотреть файл

@@ -13,13 +13,21 @@ import (
// AcceptInvitation is called when accepting an invitation to connect with a remote cluster.
func (rcs *Service) AcceptInvitation(invite *model.RemoteClusterInvite, name string, displayName string, creatorId string, siteURL string, defaultTeamId string) (*model.RemoteCluster, error) {
// Generate new token for RemoteToken only if invite version is 2 or greater
var remoteToken string
if invite.Version >= 2 {
remoteToken = model.NewId() // Generate new token for v2+ protocol
} else {
remoteToken = invite.Token // Use the token from the invite for backwards compatibility
}
rc := &model.RemoteCluster{
RemoteId: invite.RemoteId,
Name: name,
DisplayName: displayName,
DefaultTeamId: defaultTeamId,
Token: model.NewId(),
RemoteToken: invite.Token,
RemoteToken: remoteToken,
SiteURL: invite.SiteURL,
CreatorId: creatorId,
}
@@ -37,6 +45,11 @@ func (rcs *Service) AcceptInvitation(invite *model.RemoteClusterInvite, name str
url := fmt.Sprintf("%s/%s", rcSaved.SiteURL, ConfirmInviteURL)
// for the invite confirm message, we need to use the token that
// the originating server sent in the invite instead of the one
// we're storing as a refresh
rc.RemoteToken = invite.Token
resp, err := rcs.sendFrameToRemote(PingTimeout, rc, frame, url)
if err != nil {
rcs.server.GetStore().RemoteCluster().Delete(rcSaved.RemoteId)
@@ -63,9 +76,11 @@ func (rcs *Service) AcceptInvitation(invite *model.RemoteClusterInvite, name str
func makeConfirmFrame(rc *model.RemoteCluster, siteURL string) (*model.RemoteClusterFrame, error) {
confirm := model.RemoteClusterInvite{
RemoteId: rc.RemoteId,
SiteURL: siteURL,
Token: rc.Token,
RemoteId: rc.RemoteId,
SiteURL: siteURL,
Token: rc.Token,
RefreshedToken: rc.RemoteToken,
Version: 2,
}
confirmRaw, err := json.Marshal(confirm)
if err != nil {

Просмотреть файл

@@ -69,6 +69,11 @@ func (rcs *Service) ReceiveInviteConfirmation(confirm model.RemoteClusterInvite)
rc.SiteURL = confirm.SiteURL
rc.RemoteToken = confirm.Token
// If the accepting cluster sent a RefreshedToken (its RemoteToken), set it as our Token
if confirm.Version >= 2 && confirm.RefreshedToken != "" {
rc.Token = confirm.RefreshedToken
}
rcUpdated, err := store.Update(rc)
if err != nil {
return nil, fmt.Errorf("cannot apply invite confirmation for remote %s: %w", confirm.RemoteId, err)

Просмотреть файл

@@ -363,10 +363,12 @@ type RemoteClusterPing struct {
// RemoteClusterInvite represents an invitation to establish a simple trust with a remote cluster.
type RemoteClusterInvite struct {
RemoteId string `json:"remote_id"`
RemoteTeamId string `json:"remote_team_id"` // Deprecated: this field is no longer used. It's only kept for backwards compatibility.
SiteURL string `json:"site_url"`
Token string `json:"token"`
RemoteId string `json:"remote_id"`
RemoteTeamId string `json:"remote_team_id"` // Deprecated: this field is no longer used. It's only kept for backwards compatibility.
SiteURL string `json:"site_url"`
Token string `json:"token"`
RefreshedToken string `json:"refreshed_token,omitempty"` // New token generated by the remote cluster when accepting an invitation
Version int `json:"version,omitempty"`
}
func (rci *RemoteClusterInvite) IsValid() *AppError {

Просмотреть файл

@@ -160,9 +160,11 @@ func TestRemoteClusterInviteEncryption(t *testing.T) {
func makeInvite(url string) RemoteClusterInvite {
return RemoteClusterInvite{
RemoteId: NewId(),
SiteURL: url,
Token: NewId(),
RemoteId: NewId(),
SiteURL: url,
Token: NewId(),
RefreshedToken: NewId(),
Version: 2,
}
}