Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 5 additions & 17 deletions server/channels/api4/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -1652,24 +1652,12 @@ func getPostInfo(c *Context, w http.ResponseWriter, r *http.Request) {
return
}

hasPermissionToAccessChannel := false
hasJoinedChannel := false
hasPermissionToAccessChannel, hasJoinedChannel := c.App.SessionHasPermissionToReadChannel(c.AppContext, *c.AppContext.Session(), channel)

_, channelMemberErr := c.App.GetChannelMember(c.AppContext, channel.Id, userID)

if channelMemberErr == nil {
hasPermissionToAccessChannel = true
hasJoinedChannel = true
}

if !hasPermissionToAccessChannel {
if channel.Type == model.ChannelTypeOpen {
hasPermissionToAccessChannel = true
} else if channel.Type == model.ChannelTypePrivate {
hasPermissionToAccessChannel, _ = c.App.HasPermissionToChannel(c.AppContext, userID, channel.Id, model.PermissionManagePrivateChannelMembers)
} else if channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup {
hasPermissionToAccessChannel, _ = c.App.HasPermissionToReadChannel(c.AppContext, userID, channel)
}
if !hasPermissionToAccessChannel && channel.Type == model.ChannelTypeOpen && !*c.App.Config().ComplianceSettings.Enable {
canJoinOpenChannel := c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), channel.TeamId, model.PermissionJoinPublicChannels)
canJoinOpenTeam := team != nil && team.AllowOpenInvite && c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionJoinPublicTeams)
hasPermissionToAccessChannel = canJoinOpenChannel || canJoinOpenTeam
}

if !hasPermissionToAccessChannel {
Expand Down
159 changes: 158 additions & 1 deletion server/channels/api4/post_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5431,6 +5431,8 @@ func TestPostGetInfo(t *testing.T) {
mainHelper.Parallel(t)

th := Setup(t).InitBasic(t)
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true })

defaultPerms := th.SaveDefaultRolePermissions(t)
defer th.RestoreDefaultRolePermissions(t, defaultPerms)
Expand All @@ -5439,8 +5441,16 @@ func TestPostGetInfo(t *testing.T) {
th.RemovePermissionFromRole(t, model.PermissionManagePrivateChannelMembers.Id, model.TeamUserRoleId)

client := th.Client
guestUser, guestClient := th.CreateGuestAndClient(t)
otherTeamMemberClient := th.CreateClient()
_, _, err := otherTeamMemberClient.Login(context.Background(), th.BasicUser2.Username, th.BasicUser2.Password)
require.NoError(t, err)
outsiderUser := th.CreateUser(t)
outsiderClient := th.CreateClient()
_, _, err = outsiderClient.Login(context.Background(), outsiderUser.Username, outsiderUser.Password)
require.NoError(t, err)
sysadminClient := th.SystemAdminClient
_, _, err := sysadminClient.AddTeamMember(context.Background(), th.BasicTeam.Id, th.SystemAdminUser.Id)
_, _, err = sysadminClient.AddTeamMember(context.Background(), th.BasicTeam.Id, th.SystemAdminUser.Id)
require.NoError(t, err)

openChannel, _, err := client.CreateChannel(context.Background(), &model.Channel{TeamId: th.BasicTeam.Id, Type: model.ChannelTypeOpen, Name: "open-channel", DisplayName: "Open Channel"})
Expand Down Expand Up @@ -5501,6 +5511,7 @@ func TestPostGetInfo(t *testing.T) {
hasJoinedChannel bool
post *model.Post
client *model.Client4
assertSetup func(t *testing.T)
hasAccess bool
}{
// Open channel - Current Team
Expand All @@ -5524,6 +5535,25 @@ func TestPostGetInfo(t *testing.T) {
client: sysadminClient,
hasAccess: true,
},
{
name: "Open post - Current team - Guest user outside channel",
team: th.BasicTeam,
hasJoinedTeam: true,
channel: openChannel,
hasJoinedChannel: false,
post: openPost,
client: guestClient,
assertSetup: func(t *testing.T) {
t.Helper()

_, appErr := th.App.GetTeamMember(th.Context, th.BasicTeam.Id, guestUser.Id)
require.Nil(t, appErr)

_, appErr = th.App.GetChannelMember(th.Context, openChannel.Id, guestUser.Id)
require.NotNil(t, appErr)
},
hasAccess: false,
},

// Private channel - Current Team
{
Expand Down Expand Up @@ -5656,6 +5686,38 @@ func TestPostGetInfo(t *testing.T) {
client: client,
hasAccess: false,
},
{
name: "Open post - Invite team - Basic user with join private teams permission",
team: inviteTeam,
hasJoinedTeam: false,
channel: inviteTeamOpenChannel,
hasJoinedChannel: false,
post: inviteTeamOpenPost,
client: client,
assertSetup: func(t *testing.T) {
t.Helper()

_, appErr := th.App.GetTeamMember(th.Context, inviteTeam.Id, th.BasicUser.Id)
require.NotNil(t, appErr)

_, appErr = th.App.GetChannelMember(th.Context, inviteTeamOpenChannel.Id, th.BasicUser.Id)
require.NotNil(t, appErr)

require.False(t, th.App.HasPermissionToTeam(th.Context, th.BasicUser.Id, inviteTeam.Id, model.PermissionJoinPrivateTeams))
require.False(t, th.App.HasPermissionToTeam(th.Context, th.BasicUser.Id, inviteTeam.Id, model.PermissionJoinPublicChannels))

th.AddPermissionToRole(t, model.PermissionJoinPrivateTeams.Id, model.SystemUserRoleId)
th.AddPermissionToRole(t, model.PermissionJoinPublicChannels.Id, model.SystemUserRoleId)
t.Cleanup(func() {
th.RemovePermissionFromRole(t, model.PermissionJoinPublicChannels.Id, model.SystemUserRoleId)
th.RemovePermissionFromRole(t, model.PermissionJoinPrivateTeams.Id, model.SystemUserRoleId)
})

require.True(t, th.App.HasPermissionToTeam(th.Context, th.BasicUser.Id, inviteTeam.Id, model.PermissionJoinPrivateTeams))
require.True(t, th.App.HasPermissionToTeam(th.Context, th.BasicUser.Id, inviteTeam.Id, model.PermissionJoinPublicChannels))
},
hasAccess: true,
},
{
name: "Open post - Invite team - Sysadmin user",
team: inviteTeam,
Expand All @@ -5670,6 +5732,10 @@ func TestPostGetInfo(t *testing.T) {

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if tc.assertSetup != nil {
tc.assertSetup(t)
}

info, resp, err := tc.client.GetPostInfo(context.Background(), tc.post.Id)
if !tc.hasAccess {
require.Error(t, err)
Expand All @@ -5695,6 +5761,97 @@ func TestPostGetInfo(t *testing.T) {
}
})
}

t.Run("Open post - Current team - Non-member denied when compliance is enabled", func(t *testing.T) {
info, resp, err := otherTeamMemberClient.GetPostInfo(context.Background(), openPost.Id)
require.NoError(t, err)
CheckOKStatus(t, resp)
require.Equal(t, openChannel.Id, info.ChannelId)
require.True(t, info.HasJoinedTeam)
require.False(t, info.HasJoinedChannel)

originalComplianceEnabled := *th.App.Config().ComplianceSettings.Enable
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ComplianceSettings.Enable = true
})
t.Cleanup(func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ComplianceSettings.Enable = originalComplianceEnabled
})
})

_, resp, err = otherTeamMemberClient.GetPostInfo(context.Background(), openPost.Id)
require.Error(t, err)
CheckNotFoundStatus(t, resp)
})

t.Run("Open post - Open team - Non-member denied when compliance is enabled", func(t *testing.T) {
_, appErr := th.App.GetTeamMember(th.Context, openTeam.Id, th.BasicUser.Id)
require.NotNil(t, appErr)

_, appErr = th.App.GetChannelMember(th.Context, openTeamOpenChannel.Id, th.BasicUser.Id)
require.NotNil(t, appErr)

info, resp, err := client.GetPostInfo(context.Background(), openTeamOpenPost.Id)
require.NoError(t, err)
CheckOKStatus(t, resp)
require.Equal(t, openTeamOpenChannel.Id, info.ChannelId)
require.False(t, info.HasJoinedTeam)
require.False(t, info.HasJoinedChannel)

originalComplianceEnabled := *th.App.Config().ComplianceSettings.Enable
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ComplianceSettings.Enable = true
})
t.Cleanup(func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ComplianceSettings.Enable = originalComplianceEnabled
})
})

_, resp, err = client.GetPostInfo(context.Background(), openTeamOpenPost.Id)
require.Error(t, err)
CheckNotFoundStatus(t, resp)
})

t.Run("Private post - Same-team non-member with manage members permission is denied", func(t *testing.T) {
_, appErr := th.App.GetTeamMember(th.Context, th.BasicTeam.Id, th.BasicUser2.Id)
require.Nil(t, appErr)

_, appErr = th.App.GetChannelMember(th.Context, privateChannelBasicUser.Id, th.BasicUser2.Id)
require.NotNil(t, appErr)

th.AddPermissionToRole(t, model.PermissionManagePrivateChannelMembers.Id, model.TeamUserRoleId)
t.Cleanup(func() {
th.RemovePermissionFromRole(t, model.PermissionManagePrivateChannelMembers.Id, model.TeamUserRoleId)
})

hasPermission, isMember := th.App.HasPermissionToChannel(th.Context, th.BasicUser2.Id, privateChannelBasicUser.Id, model.PermissionManagePrivateChannelMembers)
require.True(t, hasPermission)
require.False(t, isMember)

_, resp, err := otherTeamMemberClient.GetPostInfo(context.Background(), privatePostBasicUser.Id)
require.Error(t, err)
CheckNotFoundStatus(t, resp)
})

t.Run("DM post - Outsider is denied", func(t *testing.T) {
_, appErr := th.App.GetChannelMember(th.Context, dmChannel.Id, outsiderUser.Id)
require.NotNil(t, appErr)

_, resp, err := outsiderClient.GetPostInfo(context.Background(), dmPost.Id)
require.Error(t, err)
CheckNotFoundStatus(t, resp)
})

t.Run("GM post - Outsider is denied", func(t *testing.T) {
_, appErr := th.App.GetChannelMember(th.Context, gmChannel.Id, outsiderUser.Id)
require.NotNil(t, appErr)

_, resp, err := outsiderClient.GetPostInfo(context.Background(), gmPost.Id)
require.Error(t, err)
CheckNotFoundStatus(t, resp)
})
}

func TestAcknowledgePost(t *testing.T) {
Expand Down
11 changes: 6 additions & 5 deletions server/channels/api4/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3973,6 +3973,7 @@ func TestResetPassword(t *testing.T) {
return tokenErr == nil
}, 10*time.Second, 500*time.Millisecond, "Recovery token not found (%s)", recoveryTokenString)

newPwd := model.NewTestPassword()
resp, err := th.Client.ResetPassword(context.Background(), recoveryToken.Token, "")
require.Error(t, err)
CheckBadRequestStatus(t, resp)
Expand All @@ -3989,16 +3990,16 @@ func TestResetPassword(t *testing.T) {
for range model.TokenSize {
code.WriteString("a")
}
resp, err = th.Client.ResetPassword(context.Background(), code.String(), "newpasswd")
resp, err = th.Client.ResetPassword(context.Background(), code.String(), newPwd)
require.Error(t, err)
CheckBadRequestStatus(t, resp)
_, err = th.Client.ResetPassword(context.Background(), recoveryToken.Token, "newpasswd")
_, err = th.Client.ResetPassword(context.Background(), recoveryToken.Token, newPwd)
require.NoError(t, err)
_, _, err = th.Client.Login(context.Background(), user.Email, "newpasswd")
_, _, err = th.Client.Login(context.Background(), user.Email, newPwd)
require.NoError(t, err)
_, err = th.Client.Logout(context.Background())
require.NoError(t, err)
resp, err = th.Client.ResetPassword(context.Background(), recoveryToken.Token, "newpasswd")
resp, err = th.Client.ResetPassword(context.Background(), recoveryToken.Token, newPwd)
require.Error(t, err)
CheckBadRequestStatus(t, resp)
authData := model.NewId()
Expand Down Expand Up @@ -4028,7 +4029,7 @@ func TestResetPasswordAuditDoesNotLeakToken(t *testing.T) {
_ = th.App.Srv().Store().Token().Delete(token.Token)
}()

_, err = th.Client.ResetPassword(context.Background(), token.Token, "newPassword1!")
_, err = th.Client.ResetPassword(context.Background(), token.Token, model.NewTestPassword())
require.NoError(t, err)

audits, appErr := th.App.GetAudits(request.EmptyContext(th.TestLogger), "", 100)
Expand Down
4 changes: 2 additions & 2 deletions server/channels/app/shared_channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,7 @@ func TestPluginAPIReceiveSharedChannelAttachmentSyncMsg(t *testing.T) {
remoteUser := &model.User{
Email: model.NewId() + "@remote.test",
Username: "remote-attach-" + model.NewId()[:8],
Password: "Password1!",
Password: model.NewTestPassword(),
RemoteId: model.NewPointer(rc.RemoteId),
}
remoteUser, appErr := th.App.CreateUser(th.Context, remoteUser)
Expand Down Expand Up @@ -1409,7 +1409,7 @@ func TestPluginAPIReceiveSharedChannelProfileImageSyncMsg(t *testing.T) {
remoteUser := &model.User{
Email: model.NewId() + "@remote.test",
Username: "remote-img-" + model.NewId()[:8],
Password: "Password1!",
Password: model.NewTestPassword(),
RemoteId: model.NewPointer(rc.RemoteId),
}
remoteUser, appErr := th.App.CreateUser(th.Context, remoteUser)
Expand Down
Loading