PLT-3346/PLT-3342/PLT-3360 EE: Add the ability to restrict channel management permissions (#3453)
* EE: Add the ability to restrict channel management permissions * Always allow last user in a channel to delete that channel
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
19d452c74e
Коммит
5f7cb8cfbf
@@ -59,6 +59,11 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
channel.TeamId = c.TeamId
|
channel.TeamId = c.TeamId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := CanManageChannel(c, channel); err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !c.HasPermissionsToTeam(channel.TeamId, "createChannel") {
|
if !c.HasPermissionsToTeam(channel.TeamId, "createChannel") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -178,6 +183,32 @@ func CreateDefaultChannels(c *Context, teamId string) ([]*model.Channel, *model.
|
|||||||
return channels, nil
|
return channels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CanManageChannel(c *Context, channel *model.Channel) *model.AppError {
|
||||||
|
if utils.IsLicensed {
|
||||||
|
if channel.Type == model.CHANNEL_OPEN {
|
||||||
|
if *utils.Cfg.TeamSettings.RestrictPublicChannelManagement == model.PERMISSIONS_SYSTEM_ADMIN && !c.IsSystemAdmin() {
|
||||||
|
return model.NewLocAppError("CanManageChannel", "api.channel.can_manage_channel.public_restricted_system_admin.app_error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if *utils.Cfg.TeamSettings.RestrictPublicChannelManagement == model.PERMISSIONS_TEAM_ADMIN && !c.IsTeamAdmin() {
|
||||||
|
return model.NewLocAppError("CanManageChannel", "api.channel.can_manage_channel.public_restricted_team_admin.app_error", nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if channel.Type == model.CHANNEL_PRIVATE {
|
||||||
|
if *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement == model.PERMISSIONS_SYSTEM_ADMIN && !c.IsSystemAdmin() {
|
||||||
|
return model.NewLocAppError("CanManageChannel", "api.channel.can_manage_channel.private_restricted_system_admin.app_error", nil, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement == model.PERMISSIONS_TEAM_ADMIN && !c.IsTeamAdmin() {
|
||||||
|
return model.NewLocAppError("CanManageChannel", "api.channel.can_manage_channel.private_restricted_team_admin.app_error", nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
channel := model.ChannelFromJson(r.Body)
|
channel := model.ChannelFromJson(r.Body)
|
||||||
@@ -198,15 +229,14 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
oldChannel := cresult.Data.(*model.Channel)
|
oldChannel := cresult.Data.(*model.Channel)
|
||||||
channelMember := cmcresult.Data.(model.ChannelMember)
|
// Don't need to do anything with channel member, just wanted to confirm it exists
|
||||||
|
|
||||||
if !c.HasPermissionsToTeam(oldChannel.TeamId, "updateChannel") {
|
if err := CanManageChannel(c, oldChannel); err != nil {
|
||||||
|
c.Err = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(channelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !c.IsTeamAdmin() {
|
if !c.HasPermissionsToTeam(oldChannel.TeamId, "updateChannel") {
|
||||||
c.Err = model.NewLocAppError("updateChannel", "api.channel.update_channel.permission.app_error", nil, "")
|
|
||||||
c.Err.StatusCode = http.StatusForbidden
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +305,12 @@ func updateChannelHeader(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
channel := cresult.Data.(*model.Channel)
|
channel := cresult.Data.(*model.Channel)
|
||||||
// Don't need to do anything channel member, just wanted to confirm it exists
|
// Don't need to do anything with channel member, just wanted to confirm it exists
|
||||||
|
|
||||||
|
if err := CanManageChannel(c, channel); err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if channel.TeamId != "" && !c.HasPermissionsToTeam(channel.TeamId, "updateChannelHeader") {
|
if channel.TeamId != "" && !c.HasPermissionsToTeam(channel.TeamId, "updateChannelHeader") {
|
||||||
return
|
return
|
||||||
@@ -348,7 +383,12 @@ func updateChannelPurpose(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
channel := cresult.Data.(*model.Channel)
|
channel := cresult.Data.(*model.Channel)
|
||||||
// Don't need to do anything channel member, just wanted to confirm it exists
|
// Don't need to do anything with channel member, just wanted to confirm it exists
|
||||||
|
|
||||||
|
if err := CanManageChannel(c, channel); err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !c.HasPermissionsToTeam(channel.TeamId, "updateChannelPurpose") {
|
if !c.HasPermissionsToTeam(channel.TeamId, "updateChannelPurpose") {
|
||||||
return
|
return
|
||||||
@@ -646,6 +686,7 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
sc := Srv.Store.Channel().Get(id)
|
sc := Srv.Store.Channel().Get(id)
|
||||||
scm := Srv.Store.Channel().GetMember(id, c.Session.UserId)
|
scm := Srv.Store.Channel().GetMember(id, c.Session.UserId)
|
||||||
|
cmc := Srv.Store.Channel().GetMemberCount(id)
|
||||||
uc := Srv.Store.User().Get(c.Session.UserId)
|
uc := Srv.Store.User().Get(c.Session.UserId)
|
||||||
ihc := Srv.Store.Webhook().GetIncomingByChannel(id)
|
ihc := Srv.Store.Webhook().GetIncomingByChannel(id)
|
||||||
ohc := Srv.Store.Webhook().GetOutgoingByChannel(id)
|
ohc := Srv.Store.Webhook().GetOutgoingByChannel(id)
|
||||||
@@ -659,6 +700,9 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
} else if scmresult := <-scm; scmresult.Err != nil {
|
} else if scmresult := <-scm; scmresult.Err != nil {
|
||||||
c.Err = scmresult.Err
|
c.Err = scmresult.Err
|
||||||
return
|
return
|
||||||
|
} else if cmcresult := <-cmc; cmcresult.Err != nil {
|
||||||
|
c.Err = cmcresult.Err
|
||||||
|
return
|
||||||
} else if ihcresult := <-ihc; ihcresult.Err != nil {
|
} else if ihcresult := <-ihc; ihcresult.Err != nil {
|
||||||
c.Err = ihcresult.Err
|
c.Err = ihcresult.Err
|
||||||
return
|
return
|
||||||
@@ -667,18 +711,21 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
channel := cresult.Data.(*model.Channel)
|
channel := cresult.Data.(*model.Channel)
|
||||||
|
memberCount := cmcresult.Data.(int64)
|
||||||
user := uresult.Data.(*model.User)
|
user := uresult.Data.(*model.User)
|
||||||
channelMember := scmresult.Data.(model.ChannelMember)
|
|
||||||
incomingHooks := ihcresult.Data.([]*model.IncomingWebhook)
|
incomingHooks := ihcresult.Data.([]*model.IncomingWebhook)
|
||||||
outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook)
|
outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook)
|
||||||
|
// Don't need to do anything with channel member, just wanted to confirm it exists
|
||||||
|
|
||||||
if !c.HasPermissionsToTeam(channel.TeamId, "deleteChannel") {
|
// Allow delete if user is the only member left in channel
|
||||||
return
|
if memberCount > 1 {
|
||||||
|
if err := CanManageChannel(c, channel); err != nil {
|
||||||
|
c.Err = err
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(channelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !c.IsTeamAdmin() {
|
if !c.HasPermissionsToTeam(channel.TeamId, "deleteChannel") {
|
||||||
c.Err = model.NewLocAppError("deleteChannel", "api.channel.delete_channel.permissions.app_error", nil, "")
|
|
||||||
c.Err.StatusCode = http.StatusForbidden
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateChannel(t *testing.T) {
|
func TestCreateChannel(t *testing.T) {
|
||||||
th := Setup().InitBasic()
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
Client := th.BasicClient
|
Client := th.BasicClient
|
||||||
|
SystemAdminClient := th.SystemAdminClient
|
||||||
team := th.BasicTeam
|
team := th.BasicTeam
|
||||||
Client.Must(Client.Logout())
|
Client.Must(Client.Logout())
|
||||||
team2 := th.CreateTeam(th.BasicClient)
|
team2 := th.CreateTeam(th.BasicClient)
|
||||||
@@ -74,6 +75,12 @@ func TestCreateChannel(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channel = model.Channel{DisplayName: "Channel With No TeamId", Name: "aaaa" + model.NewId() + "abbb", Type: model.CHANNEL_OPEN, TeamId: ""}
|
||||||
|
|
||||||
|
if _, err := Client.CreateChannel(&channel); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
channel = model.Channel{DisplayName: "Test API Name", Name: model.NewId() + "__" + model.NewId(), Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
channel = model.Channel{DisplayName: "Test API Name", Name: model.NewId() + "__" + model.NewId(), Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||||
|
|
||||||
if _, err := Client.CreateChannel(&channel); err == nil {
|
if _, err := Client.CreateChannel(&channel); err == nil {
|
||||||
@@ -85,6 +92,72 @@ func TestCreateChannel(t *testing.T) {
|
|||||||
if _, err := Client.CreateChannel(&channel); err == nil {
|
if _, err := Client.CreateChannel(&channel); err == nil {
|
||||||
t.Fatal("Should have errored out on direct channel type")
|
t.Fatal("Should have errored out on direct channel type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLicensed := utils.IsLicensed
|
||||||
|
restrictPublicChannel := *utils.Cfg.TeamSettings.RestrictPublicChannelManagement
|
||||||
|
restrictPrivateChannel := *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement
|
||||||
|
defer func() {
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
|
||||||
|
utils.IsLicensed = isLicensed
|
||||||
|
}()
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
utils.IsLicensed = true
|
||||||
|
|
||||||
|
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||||
|
channel3 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
|
||||||
|
if _, err := Client.CreateChannel(channel2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.CreateChannel(channel3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
|
||||||
|
channel2.Name = "a" + model.NewId() + "a"
|
||||||
|
channel3.Name = "a" + model.NewId() + "a"
|
||||||
|
if _, err := Client.CreateChannel(channel2); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.CreateChannel(channel3); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateUserToTeamAdmin(th.BasicUser, team)
|
||||||
|
Client.Logout()
|
||||||
|
th.LoginBasic()
|
||||||
|
Client.SetTeamId(team.Id)
|
||||||
|
|
||||||
|
if _, err := Client.CreateChannel(channel2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.CreateChannel(channel3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
|
||||||
|
channel2.Name = "a" + model.NewId() + "a"
|
||||||
|
channel3.Name = "a" + model.NewId() + "a"
|
||||||
|
if _, err := Client.CreateChannel(channel2); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.CreateChannel(channel3); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkUserToTeam(th.SystemAdminUser, team)
|
||||||
|
|
||||||
|
if _, err := SystemAdminClient.CreateChannel(channel2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := SystemAdminClient.CreateChannel(channel3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateDirectChannel(t *testing.T) {
|
func TestCreateDirectChannel(t *testing.T) {
|
||||||
@@ -129,7 +202,7 @@ func TestCreateDirectChannel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateChannel(t *testing.T) {
|
func TestUpdateChannel(t *testing.T) {
|
||||||
th := Setup().InitSystemAdmin()
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
Client := th.SystemAdminClient
|
Client := th.SystemAdminClient
|
||||||
team := th.SystemAdminTeam
|
team := th.SystemAdminTeam
|
||||||
sysAdminUser := th.SystemAdminUser
|
sysAdminUser := th.SystemAdminUser
|
||||||
@@ -193,6 +266,7 @@ func TestUpdateChannel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Client.Login(sysAdminUser.Email, sysAdminUser.Password)
|
Client.Login(sysAdminUser.Email, sysAdminUser.Password)
|
||||||
|
LinkUserToTeam(sysAdminUser, team)
|
||||||
Client.Must(Client.JoinChannel(channel1.Id))
|
Client.Must(Client.JoinChannel(channel1.Id))
|
||||||
|
|
||||||
if _, err := Client.UpdateChannel(upChannel1); err != nil {
|
if _, err := Client.UpdateChannel(upChannel1); err != nil {
|
||||||
@@ -204,11 +278,82 @@ func TestUpdateChannel(t *testing.T) {
|
|||||||
if _, err := Client.UpdateChannel(upChannel1); err == nil {
|
if _, err := Client.UpdateChannel(upChannel1); err == nil {
|
||||||
t.Fatal("should have failed - channel deleted")
|
t.Fatal("should have failed - channel deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLicensed := utils.IsLicensed
|
||||||
|
restrictPublicChannel := *utils.Cfg.TeamSettings.RestrictPublicChannelManagement
|
||||||
|
restrictPrivateChannel := *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement
|
||||||
|
defer func() {
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
|
||||||
|
utils.IsLicensed = isLicensed
|
||||||
|
}()
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
utils.IsLicensed = true
|
||||||
|
|
||||||
|
channel2 := th.CreateChannel(Client, team)
|
||||||
|
channel3 := th.CreatePrivateChannel(Client, team)
|
||||||
|
|
||||||
|
LinkUserToTeam(th.BasicUser, team)
|
||||||
|
|
||||||
|
Client.Must(Client.AddChannelMember(channel2.Id, th.BasicUser.Id))
|
||||||
|
Client.Must(Client.AddChannelMember(channel3.Id, th.BasicUser.Id))
|
||||||
|
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannel(channel2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannel(channel3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannel(channel2); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannel(channel3); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateUserToTeamAdmin(th.BasicUser, team)
|
||||||
|
Client.Logout()
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
Client.SetTeamId(team.Id)
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannel(channel2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannel(channel3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannel(channel2); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannel(channel3); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
th.LoginSystemAdmin()
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannel(channel2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannel(channel3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateChannelHeader(t *testing.T) {
|
func TestUpdateChannelHeader(t *testing.T) {
|
||||||
th := Setup().InitBasic()
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
Client := th.BasicClient
|
Client := th.BasicClient
|
||||||
|
SystemAdminClient := th.SystemAdminClient
|
||||||
team := th.BasicTeam
|
team := th.BasicTeam
|
||||||
|
|
||||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||||
@@ -266,11 +411,89 @@ func TestUpdateChannelHeader(t *testing.T) {
|
|||||||
if _, err := Client.UpdateChannelHeader(data); err == nil {
|
if _, err := Client.UpdateChannelHeader(data); err == nil {
|
||||||
t.Fatal("should have errored non-channel member trying to update header")
|
t.Fatal("should have errored non-channel member trying to update header")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLicensed := utils.IsLicensed
|
||||||
|
restrictPublicChannel := *utils.Cfg.TeamSettings.RestrictPublicChannelManagement
|
||||||
|
restrictPrivateChannel := *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement
|
||||||
|
defer func() {
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
|
||||||
|
utils.IsLicensed = isLicensed
|
||||||
|
}()
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
utils.IsLicensed = true
|
||||||
|
|
||||||
|
th.LoginBasic()
|
||||||
|
channel2 := th.CreateChannel(Client, team)
|
||||||
|
channel3 := th.CreatePrivateChannel(Client, team)
|
||||||
|
|
||||||
|
data2 := make(map[string]string)
|
||||||
|
data2["channel_id"] = channel2.Id
|
||||||
|
data2["channel_header"] = "new header"
|
||||||
|
|
||||||
|
data3 := make(map[string]string)
|
||||||
|
data3["channel_id"] = channel3.Id
|
||||||
|
data3["channel_header"] = "new header"
|
||||||
|
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelHeader(data2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelHeader(data3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelHeader(data2); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelHeader(data3); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateUserToTeamAdmin(th.BasicUser, team)
|
||||||
|
Client.Logout()
|
||||||
|
th.LoginBasic()
|
||||||
|
Client.SetTeamId(team.Id)
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelHeader(data2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelHeader(data3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelHeader(data2); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelHeader(data3); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkUserToTeam(th.SystemAdminUser, team)
|
||||||
|
Client.Must(Client.AddChannelMember(channel2.Id, th.SystemAdminUser.Id))
|
||||||
|
Client.Must(Client.AddChannelMember(channel3.Id, th.SystemAdminUser.Id))
|
||||||
|
th.LoginSystemAdmin()
|
||||||
|
|
||||||
|
if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := SystemAdminClient.UpdateChannelHeader(data3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateChannelPurpose(t *testing.T) {
|
func TestUpdateChannelPurpose(t *testing.T) {
|
||||||
th := Setup().InitBasic()
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
Client := th.BasicClient
|
Client := th.BasicClient
|
||||||
|
SystemAdminClient := th.SystemAdminClient
|
||||||
team := th.BasicTeam
|
team := th.BasicTeam
|
||||||
|
|
||||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||||
@@ -314,6 +537,83 @@ func TestUpdateChannelPurpose(t *testing.T) {
|
|||||||
if _, err := Client.UpdateChannelPurpose(data); err == nil {
|
if _, err := Client.UpdateChannelPurpose(data); err == nil {
|
||||||
t.Fatal("should have errored non-channel member trying to update purpose")
|
t.Fatal("should have errored non-channel member trying to update purpose")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLicensed := utils.IsLicensed
|
||||||
|
restrictPublicChannel := *utils.Cfg.TeamSettings.RestrictPublicChannelManagement
|
||||||
|
restrictPrivateChannel := *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement
|
||||||
|
defer func() {
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
|
||||||
|
utils.IsLicensed = isLicensed
|
||||||
|
}()
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
utils.IsLicensed = true
|
||||||
|
|
||||||
|
th.LoginBasic()
|
||||||
|
channel2 := th.CreateChannel(Client, team)
|
||||||
|
channel3 := th.CreatePrivateChannel(Client, team)
|
||||||
|
|
||||||
|
data2 := make(map[string]string)
|
||||||
|
data2["channel_id"] = channel2.Id
|
||||||
|
data2["channel_purpose"] = "new purpose"
|
||||||
|
|
||||||
|
data3 := make(map[string]string)
|
||||||
|
data3["channel_id"] = channel3.Id
|
||||||
|
data3["channel_purpose"] = "new purpose"
|
||||||
|
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data2); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data3); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateUserToTeamAdmin(th.BasicUser, team)
|
||||||
|
Client.Logout()
|
||||||
|
th.LoginBasic()
|
||||||
|
Client.SetTeamId(team.Id)
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data2); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.UpdateChannelPurpose(data3); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkUserToTeam(th.SystemAdminUser, team)
|
||||||
|
Client.Must(Client.AddChannelMember(channel2.Id, th.SystemAdminUser.Id))
|
||||||
|
Client.Must(Client.AddChannelMember(channel3.Id, th.SystemAdminUser.Id))
|
||||||
|
th.LoginSystemAdmin()
|
||||||
|
|
||||||
|
if _, err := SystemAdminClient.UpdateChannelPurpose(data2); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := SystemAdminClient.UpdateChannelPurpose(data3); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetChannel(t *testing.T) {
|
func TestGetChannel(t *testing.T) {
|
||||||
@@ -572,7 +872,7 @@ func TestLeaveChannel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteChannel(t *testing.T) {
|
func TestDeleteChannel(t *testing.T) {
|
||||||
th := Setup().InitSystemAdmin()
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
Client := th.SystemAdminClient
|
Client := th.SystemAdminClient
|
||||||
team := th.SystemAdminTeam
|
team := th.SystemAdminTeam
|
||||||
userSystemAdmin := th.SystemAdminUser
|
userSystemAdmin := th.SystemAdminUser
|
||||||
@@ -619,8 +919,8 @@ func TestDeleteChannel(t *testing.T) {
|
|||||||
|
|
||||||
Client.Must(Client.JoinChannel(channel2.Id))
|
Client.Must(Client.JoinChannel(channel2.Id))
|
||||||
|
|
||||||
if _, err := Client.DeleteChannel(channel2.Id); err == nil {
|
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
|
||||||
t.Fatal("should have failed to delete channel you're not an admin of")
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rget := Client.Must(Client.GetChannels(""))
|
rget := Client.Must(Client.GetChannels(""))
|
||||||
@@ -640,6 +940,8 @@ func TestDeleteChannel(t *testing.T) {
|
|||||||
Client.Login(userStd.Email, userStd.Password)
|
Client.Login(userStd.Email, userStd.Password)
|
||||||
Client.SetTeamId(team.Id)
|
Client.SetTeamId(team.Id)
|
||||||
|
|
||||||
|
channel2 = th.CreateChannel(Client, team)
|
||||||
|
|
||||||
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
|
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -657,6 +959,102 @@ func TestDeleteChannel(t *testing.T) {
|
|||||||
if _, err := Client.DeleteChannel(channel3.Id); err == nil {
|
if _, err := Client.DeleteChannel(channel3.Id); err == nil {
|
||||||
t.Fatal("should have failed - channel already deleted")
|
t.Fatal("should have failed - channel already deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLicensed := utils.IsLicensed
|
||||||
|
restrictPublicChannel := *utils.Cfg.TeamSettings.RestrictPublicChannelManagement
|
||||||
|
restrictPrivateChannel := *utils.Cfg.TeamSettings.RestrictPrivateChannelManagement
|
||||||
|
defer func() {
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
|
||||||
|
utils.IsLicensed = isLicensed
|
||||||
|
}()
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
|
||||||
|
utils.IsLicensed = true
|
||||||
|
|
||||||
|
th.LoginSystemAdmin()
|
||||||
|
LinkUserToTeam(th.BasicUser, team)
|
||||||
|
|
||||||
|
channel2 = th.CreateChannel(Client, team)
|
||||||
|
channel3 = th.CreatePrivateChannel(Client, team)
|
||||||
|
channel4 := th.CreateChannel(Client, team)
|
||||||
|
Client.Must(Client.AddChannelMember(channel2.Id, th.BasicUser.Id))
|
||||||
|
Client.Must(Client.AddChannelMember(channel3.Id, th.BasicUser.Id))
|
||||||
|
Client.Must(Client.AddChannelMember(channel4.Id, th.BasicUser.Id))
|
||||||
|
Client.Must(Client.LeaveChannel(channel4.Id))
|
||||||
|
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
|
||||||
|
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.DeleteChannel(channel3.Id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
|
||||||
|
th.LoginSystemAdmin()
|
||||||
|
|
||||||
|
channel2 = th.CreateChannel(Client, team)
|
||||||
|
channel3 = th.CreatePrivateChannel(Client, team)
|
||||||
|
Client.Must(Client.AddChannelMember(channel2.Id, th.BasicUser.Id))
|
||||||
|
Client.Must(Client.AddChannelMember(channel3.Id, th.BasicUser.Id))
|
||||||
|
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
|
||||||
|
if _, err := Client.DeleteChannel(channel2.Id); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.DeleteChannel(channel3.Id); err == nil {
|
||||||
|
t.Fatal("should have errored not team admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateUserToTeamAdmin(th.BasicUser, team)
|
||||||
|
Client.Logout()
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
Client.SetTeamId(team.Id)
|
||||||
|
|
||||||
|
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.DeleteChannel(channel3.Id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
|
||||||
|
th.LoginSystemAdmin()
|
||||||
|
|
||||||
|
channel2 = th.CreateChannel(Client, team)
|
||||||
|
channel3 = th.CreatePrivateChannel(Client, team)
|
||||||
|
Client.Must(Client.AddChannelMember(channel2.Id, th.BasicUser.Id))
|
||||||
|
Client.Must(Client.AddChannelMember(channel3.Id, th.BasicUser.Id))
|
||||||
|
|
||||||
|
Client.Login(th.BasicUser.Email, th.BasicUser.Password)
|
||||||
|
|
||||||
|
if _, err := Client.DeleteChannel(channel2.Id); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
if _, err := Client.DeleteChannel(channel3.Id); err == nil {
|
||||||
|
t.Fatal("should have errored not system admin")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only one left in channel, should be able to delete
|
||||||
|
if _, err := Client.DeleteChannel(channel4.Id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
th.LoginSystemAdmin()
|
||||||
|
|
||||||
|
if _, err := Client.DeleteChannel(channel2.Id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := Client.DeleteChannel(channel3.Id); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetChannelExtraInfo(t *testing.T) {
|
func TestGetChannelExtraInfo(t *testing.T) {
|
||||||
|
|||||||
@@ -400,12 +400,12 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if utils.IsLicensed {
|
if utils.IsLicensed {
|
||||||
if *utils.Cfg.TeamSettings.RestrictTeamInvite == model.TEAM_INVITE_SYSTEM_ADMIN && !c.IsSystemAdmin() {
|
if *utils.Cfg.TeamSettings.RestrictTeamInvite == model.PERMISSIONS_SYSTEM_ADMIN && !c.IsSystemAdmin() {
|
||||||
c.Err = model.NewLocAppError("inviteMembers", "api.team.invite_members.restricted_system_admin.app_error", nil, "")
|
c.Err = model.NewLocAppError("inviteMembers", "api.team.invite_members.restricted_system_admin.app_error", nil, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if *utils.Cfg.TeamSettings.RestrictTeamInvite == model.TEAM_INVITE_TEAM_ADMIN && !c.IsTeamAdmin() {
|
if *utils.Cfg.TeamSettings.RestrictTeamInvite == model.PERMISSIONS_TEAM_ADMIN && !c.IsTeamAdmin() {
|
||||||
c.Err = model.NewLocAppError("inviteMembers", "api.team.invite_members.restricted_team_admin.app_error", nil, "")
|
c.Err = model.NewLocAppError("inviteMembers", "api.team.invite_members.restricted_team_admin.app_error", nil, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ func TestInviteMembers(t *testing.T) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
*utils.Cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite
|
*utils.Cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite
|
||||||
}()
|
}()
|
||||||
*utils.Cfg.TeamSettings.RestrictTeamInvite = model.TEAM_INVITE_TEAM_ADMIN
|
*utils.Cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN
|
||||||
|
|
||||||
th.LoginBasic2()
|
th.LoginBasic2()
|
||||||
LinkUserToTeam(th.BasicUser2, team)
|
LinkUserToTeam(th.BasicUser2, team)
|
||||||
@@ -427,7 +427,7 @@ func TestInviteMembers(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
*utils.Cfg.TeamSettings.RestrictTeamInvite = model.TEAM_INVITE_SYSTEM_ADMIN
|
*utils.Cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN
|
||||||
|
|
||||||
if _, err := Client.InviteMembers(invites); err == nil {
|
if _, err := Client.InviteMembers(invites); err == nil {
|
||||||
t.Fatal("should have errored not system admin and licensed")
|
t.Fatal("should have errored not system admin and licensed")
|
||||||
|
|||||||
@@ -38,7 +38,9 @@
|
|||||||
"EnableCustomBrand": false,
|
"EnableCustomBrand": false,
|
||||||
"CustomBrandText": "",
|
"CustomBrandText": "",
|
||||||
"RestrictDirectMessage": "any",
|
"RestrictDirectMessage": "any",
|
||||||
"RestrictTeamInvite": "system_admin"
|
"RestrictTeamInvite": "all",
|
||||||
|
"RestrictPublicChannelManagement": "all",
|
||||||
|
"RestrictPrivateChannelManagement": "all"
|
||||||
},
|
},
|
||||||
"SqlSettings": {
|
"SqlSettings": {
|
||||||
"DriverName": "mysql",
|
"DriverName": "mysql",
|
||||||
|
|||||||
16
i18n/en.json
16
i18n/en.json
@@ -311,6 +311,22 @@
|
|||||||
"id": "api.channel.update_channel.deleted.app_error",
|
"id": "api.channel.update_channel.deleted.app_error",
|
||||||
"translation": "The channel has been archived or deleted"
|
"translation": "The channel has been archived or deleted"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.channel.can_manage_channel.public_restricted_system_admin.app_error",
|
||||||
|
"translation": "Public Channel management and creation is restricted to System Administrators."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.channel.can_manage_channel.public_restricted_team_admin.app_error",
|
||||||
|
"translation": "Public Channel management and creation is restricted to Team and System Administrators."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.channel.can_manage_channel.private_restricted_system_admin.app_error",
|
||||||
|
"translation": "Private Group management and creation is restricted to System Administrators."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.channel.can_manage_channel.private_restricted_team_admin.app_error",
|
||||||
|
"translation": "Private Group management and creation is restricted to Team and System Administrators."
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api.channel.update_channel.permission.app_error",
|
"id": "api.channel.update_channel.permission.app_error",
|
||||||
"translation": "You do not have the appropriate permissions"
|
"translation": "You do not have the appropriate permissions"
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ const (
|
|||||||
DIRECT_MESSAGE_ANY = "any"
|
DIRECT_MESSAGE_ANY = "any"
|
||||||
DIRECT_MESSAGE_TEAM = "team"
|
DIRECT_MESSAGE_TEAM = "team"
|
||||||
|
|
||||||
TEAM_INVITE_ALL = "all"
|
PERMISSIONS_ALL = "all"
|
||||||
TEAM_INVITE_TEAM_ADMIN = "team_admin"
|
PERMISSIONS_TEAM_ADMIN = "team_admin"
|
||||||
TEAM_INVITE_SYSTEM_ADMIN = "system_admin"
|
PERMISSIONS_SYSTEM_ADMIN = "system_admin"
|
||||||
|
|
||||||
FAKE_SETTING = "********************************"
|
FAKE_SETTING = "********************************"
|
||||||
|
|
||||||
@@ -169,17 +169,19 @@ type SupportSettings struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TeamSettings struct {
|
type TeamSettings struct {
|
||||||
SiteName string
|
SiteName string
|
||||||
MaxUsersPerTeam int
|
MaxUsersPerTeam int
|
||||||
EnableTeamCreation bool
|
EnableTeamCreation bool
|
||||||
EnableUserCreation bool
|
EnableUserCreation bool
|
||||||
EnableOpenServer *bool
|
EnableOpenServer *bool
|
||||||
RestrictCreationToDomains string
|
RestrictCreationToDomains string
|
||||||
RestrictTeamNames *bool
|
RestrictTeamNames *bool
|
||||||
EnableCustomBrand *bool
|
EnableCustomBrand *bool
|
||||||
CustomBrandText *string
|
CustomBrandText *string
|
||||||
RestrictDirectMessage *string
|
RestrictDirectMessage *string
|
||||||
RestrictTeamInvite *string
|
RestrictTeamInvite *string
|
||||||
|
RestrictPublicChannelManagement *string
|
||||||
|
RestrictPrivateChannelManagement *string
|
||||||
}
|
}
|
||||||
|
|
||||||
type LdapSettings struct {
|
type LdapSettings struct {
|
||||||
@@ -381,7 +383,17 @@ func (o *Config) SetDefaults() {
|
|||||||
|
|
||||||
if o.TeamSettings.RestrictTeamInvite == nil {
|
if o.TeamSettings.RestrictTeamInvite == nil {
|
||||||
o.TeamSettings.RestrictTeamInvite = new(string)
|
o.TeamSettings.RestrictTeamInvite = new(string)
|
||||||
*o.TeamSettings.RestrictTeamInvite = TEAM_INVITE_ALL
|
*o.TeamSettings.RestrictTeamInvite = PERMISSIONS_ALL
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.TeamSettings.RestrictPublicChannelManagement == nil {
|
||||||
|
o.TeamSettings.RestrictPublicChannelManagement = new(string)
|
||||||
|
*o.TeamSettings.RestrictPublicChannelManagement = PERMISSIONS_ALL
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.TeamSettings.RestrictPrivateChannelManagement == nil {
|
||||||
|
o.TeamSettings.RestrictPrivateChannelManagement = new(string)
|
||||||
|
*o.TeamSettings.RestrictPrivateChannelManagement = PERMISSIONS_ALL
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.EmailSettings.EnableSignInWithEmail == nil {
|
if o.EmailSettings.EnableSignInWithEmail == nil {
|
||||||
|
|||||||
@@ -215,6 +215,8 @@ func getClientConfig(c *model.Config) map[string]string {
|
|||||||
props["RestrictTeamNames"] = strconv.FormatBool(*c.TeamSettings.RestrictTeamNames)
|
props["RestrictTeamNames"] = strconv.FormatBool(*c.TeamSettings.RestrictTeamNames)
|
||||||
props["RestrictDirectMessage"] = *c.TeamSettings.RestrictDirectMessage
|
props["RestrictDirectMessage"] = *c.TeamSettings.RestrictDirectMessage
|
||||||
props["RestrictTeamInvite"] = *c.TeamSettings.RestrictTeamInvite
|
props["RestrictTeamInvite"] = *c.TeamSettings.RestrictTeamInvite
|
||||||
|
props["RestrictPublicChannelManagement"] = *c.TeamSettings.RestrictPublicChannelManagement
|
||||||
|
props["RestrictPrivateChannelManagement"] = *c.TeamSettings.RestrictPrivateChannelManagement
|
||||||
|
|
||||||
props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider)
|
props["EnableOAuthServiceProvider"] = strconv.FormatBool(c.ServiceSettings.EnableOAuthServiceProvider)
|
||||||
props["SegmentDeveloperKey"] = c.ServiceSettings.SegmentDeveloperKey
|
props["SegmentDeveloperKey"] = c.ServiceSettings.SegmentDeveloperKey
|
||||||
|
|||||||
@@ -21,12 +21,16 @@ export default class PolicySettings extends AdminSettings {
|
|||||||
this.renderSettings = this.renderSettings.bind(this);
|
this.renderSettings = this.renderSettings.bind(this);
|
||||||
|
|
||||||
this.state = Object.assign(this.state, {
|
this.state = Object.assign(this.state, {
|
||||||
restrictTeamInvite: props.config.TeamSettings.RestrictTeamInvite
|
restrictTeamInvite: props.config.TeamSettings.RestrictTeamInvite,
|
||||||
|
restrictPublicChannelManagement: props.config.TeamSettings.RestrictPublicChannelManagement,
|
||||||
|
restrictPrivateChannelManagement: props.config.TeamSettings.RestrictPrivateChannelManagement
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getConfigFromState(config) {
|
getConfigFromState(config) {
|
||||||
config.TeamSettings.RestrictTeamInvite = this.state.restrictTeamInvite;
|
config.TeamSettings.RestrictTeamInvite = this.state.restrictTeamInvite;
|
||||||
|
config.TeamSettings.RestrictPublicChannelManagement = this.state.restrictPublicChannelManagement;
|
||||||
|
config.TeamSettings.RestrictPrivateChannelManagement = this.state.restrictPrivateChannelManagement;
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
@@ -48,9 +52,9 @@ export default class PolicySettings extends AdminSettings {
|
|||||||
<DropdownSetting
|
<DropdownSetting
|
||||||
id='restrictTeamInvite'
|
id='restrictTeamInvite'
|
||||||
values={[
|
values={[
|
||||||
{value: Constants.TEAM_INVITE_ALL, text: Utils.localizeMessage('admin.general.policy.teamInviteAll', 'All team members')},
|
{value: Constants.PERMISSIONS_ALL, text: Utils.localizeMessage('admin.general.policy.permissionsAll', 'All team members')},
|
||||||
{value: Constants.TEAM_INVITE_TEAM_ADMIN, text: Utils.localizeMessage('admin.general.policy.teamInviteAdmin', 'Team and System Admins')},
|
{value: Constants.PERMISSIONS_TEAM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsAdmin', 'Team and System Admins')},
|
||||||
{value: Constants.TEAM_INVITE_SYSTEM_ADMIN, text: Utils.localizeMessage('admin.general.policy.teamInviteSystemAdmin', 'System Admins')}
|
{value: Constants.PERMISSIONS_SYSTEM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsSystemAdmin', 'System Admins')}
|
||||||
]}
|
]}
|
||||||
label={
|
label={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
@@ -67,6 +71,50 @@ export default class PolicySettings extends AdminSettings {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
<DropdownSetting
|
||||||
|
id='restrictPublicChannelManagement'
|
||||||
|
values={[
|
||||||
|
{value: Constants.PERMISSIONS_ALL, text: Utils.localizeMessage('admin.general.policy.permissionsAll', 'All team members')},
|
||||||
|
{value: Constants.PERMISSIONS_TEAM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsAdmin', 'Team and System Admins')},
|
||||||
|
{value: Constants.PERMISSIONS_SYSTEM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsSystemAdmin', 'System Admins')}
|
||||||
|
]}
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='admin.general.policy.restrictPublicChannelManagementTitle'
|
||||||
|
defaultMessage='Enable public channel management permissions for:'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value={this.state.restrictPublicChannelManagement}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
helpText={
|
||||||
|
<FormattedHTMLMessage
|
||||||
|
id='admin.general.policy.restrictPublicChannelManagementDescription'
|
||||||
|
defaultMessage='Selecting "All team members" allows any team members to create, delete, rename, and set the header or purpose for public channels.<br/><br/>Selecting "Team and System Admins" restricts channel management permissions for public channels to Team and System Admins, including creating, deleting, renaming, and setting the channel header or purpose.<br/><br/>Selecting "System Admins" restricts channel management permissions for public channels to System Admins, including creating, deleting, renaming, and setting the channel header or purpose.'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DropdownSetting
|
||||||
|
id='restrictPrivateChannelManagement'
|
||||||
|
values={[
|
||||||
|
{value: Constants.PERMISSIONS_ALL, text: Utils.localizeMessage('admin.general.policy.permissionsAll', 'All team members')},
|
||||||
|
{value: Constants.PERMISSIONS_TEAM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsAdmin', 'Team and System Admins')},
|
||||||
|
{value: Constants.PERMISSIONS_SYSTEM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsSystemAdmin', 'System Admins')}
|
||||||
|
]}
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
id='admin.general.policy.restrictPrivateChannelManagementTitle'
|
||||||
|
defaultMessage='Enable private group management permissions for:'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
value={this.state.restrictPrivateChannelManagement}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
helpText={
|
||||||
|
<FormattedHTMLMessage
|
||||||
|
id='admin.general.policy.restrictPrivateChannelManagementDescription'
|
||||||
|
defaultMessage='Selecting "All team members" allows any team members to create, delete, rename, and set the header or purpose for private groups.<br/><br/>Selecting "Team and System Admins" restricts group management permissions for private groups to Team and System Admins, including creating, deleting, renaming, and setting the group header or purpose.<br/><br/>Selecting "System Admins" restricts group management permissions for private groups to System Admins, including creating, deleting, renaming, and setting the group header or purpose.'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</SettingsGroup>
|
</SettingsGroup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
state.showRenameChannelModal = false;
|
state.showRenameChannelModal = false;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateFromStores() {
|
getStateFromStores() {
|
||||||
const extraInfo = ChannelStore.getExtraInfo(this.props.channelId);
|
const extraInfo = ChannelStore.getExtraInfo(this.props.channelId);
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
currentUser: UserStore.getCurrentUser()
|
currentUser: UserStore.getCurrentUser()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
validState() {
|
validState() {
|
||||||
if (!this.state.channel ||
|
if (!this.state.channel ||
|
||||||
!this.state.memberChannel ||
|
!this.state.memberChannel ||
|
||||||
@@ -77,6 +79,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
ChannelStore.addChangeListener(this.onListenerChange);
|
ChannelStore.addChangeListener(this.onListenerChange);
|
||||||
ChannelStore.addExtraInfoChangeListener(this.onListenerChange);
|
ChannelStore.addExtraInfoChangeListener(this.onListenerChange);
|
||||||
@@ -87,6 +90,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
$('.sidebar--left .dropdown-menu').perfectScrollbar();
|
$('.sidebar--left .dropdown-menu').perfectScrollbar();
|
||||||
document.addEventListener('keydown', this.openRecentMentions);
|
document.addEventListener('keydown', this.openRecentMentions);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
ChannelStore.removeChangeListener(this.onListenerChange);
|
ChannelStore.removeChangeListener(this.onListenerChange);
|
||||||
ChannelStore.removeExtraInfoChangeListener(this.onListenerChange);
|
ChannelStore.removeExtraInfoChangeListener(this.onListenerChange);
|
||||||
@@ -96,6 +100,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
UserStore.removeStatusesChangeListener(this.onListenerChange);
|
UserStore.removeStatusesChangeListener(this.onListenerChange);
|
||||||
document.removeEventListener('keydown', this.openRecentMentions);
|
document.removeEventListener('keydown', this.openRecentMentions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onListenerChange() {
|
onListenerChange() {
|
||||||
const newState = this.getStateFromStores();
|
const newState = this.getStateFromStores();
|
||||||
if (!Utils.areObjectsEqual(newState, this.state)) {
|
if (!Utils.areObjectsEqual(newState, this.state)) {
|
||||||
@@ -103,6 +108,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
}
|
}
|
||||||
$('.channel-header__info .description').popover({placement: 'bottom', trigger: 'hover', html: true, delay: {show: 500, hide: 500}});
|
$('.channel-header__info .description').popover({placement: 'bottom', trigger: 'hover', html: true, delay: {show: 500, hide: 500}});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLeave() {
|
handleLeave() {
|
||||||
Client.leaveChannel(this.state.channel.id,
|
Client.leaveChannel(this.state.channel.id,
|
||||||
() => {
|
() => {
|
||||||
@@ -119,6 +125,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchMentions(e) {
|
searchMentions(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -146,12 +153,14 @@ export default class ChannelHeader extends React.Component {
|
|||||||
is_mention_search: true
|
is_mention_search: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openRecentMentions(e) {
|
openRecentMentions(e) {
|
||||||
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.keyCode === Constants.KeyCodes.M) {
|
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.keyCode === Constants.KeyCodes.M) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.searchMentions(e);
|
this.searchMentions(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showRenameChannelModal(e) {
|
showRenameChannelModal(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -159,6 +168,7 @@ export default class ChannelHeader extends React.Component {
|
|||||||
showRenameChannelModal: true
|
showRenameChannelModal: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hideRenameChannelModal() {
|
hideRenameChannelModal() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showRenameChannelModal: false
|
showRenameChannelModal: false
|
||||||
@@ -179,6 +189,30 @@ export default class ChannelHeader extends React.Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showManagementOptions(channel, isAdmin, isSystemAdmin) {
|
||||||
|
if (global.window.mm_license.IsLicensed !== 'true') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel.type === Constants.OPEN_CHANNEL) {
|
||||||
|
if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (channel.type === Constants.PRIVATE_CHANNEL) {
|
||||||
|
if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.validState()) {
|
if (!this.validState()) {
|
||||||
return null;
|
return null;
|
||||||
@@ -210,7 +244,8 @@ export default class ChannelHeader extends React.Component {
|
|||||||
);
|
);
|
||||||
let channelTitle = channel.display_name;
|
let channelTitle = channel.display_name;
|
||||||
const currentId = this.state.currentUser.id;
|
const currentId = this.state.currentUser.id;
|
||||||
const isAdmin = Utils.isAdmin(this.state.memberChannel.roles) || TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
||||||
|
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||||
const isDirect = (this.state.channel.type === 'D');
|
const isDirect = (this.state.channel.type === 'D');
|
||||||
|
|
||||||
if (isDirect) {
|
if (isDirect) {
|
||||||
@@ -329,46 +364,6 @@ export default class ChannelHeader extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dropdownContents.push(
|
|
||||||
<li
|
|
||||||
key='set_channel_header'
|
|
||||||
role='presentation'
|
|
||||||
>
|
|
||||||
<ToggleModalButton
|
|
||||||
role='menuitem'
|
|
||||||
dialogType={EditChannelHeaderModal}
|
|
||||||
dialogProps={{channel}}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_header.setHeader'
|
|
||||||
defaultMessage='Set {term} Header...'
|
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ToggleModalButton>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
dropdownContents.push(
|
|
||||||
<li
|
|
||||||
key='set_channel_purpose'
|
|
||||||
role='presentation'
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
role='menuitem'
|
|
||||||
href='#'
|
|
||||||
onClick={() => this.setState({showEditChannelPurposeModal: true})}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_header.setPurpose'
|
|
||||||
defaultMessage='Set {term} Purpose...'
|
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
dropdownContents.push(
|
dropdownContents.push(
|
||||||
<li
|
<li
|
||||||
key='notification_preferences'
|
key='notification_preferences'
|
||||||
@@ -391,7 +386,70 @@ export default class ChannelHeader extends React.Component {
|
|||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isAdmin) {
|
const deleteOption = (
|
||||||
|
<li
|
||||||
|
key='delete_channel'
|
||||||
|
role='presentation'
|
||||||
|
>
|
||||||
|
<ToggleModalButton
|
||||||
|
role='menuitem'
|
||||||
|
dialogType={DeleteChannelModal}
|
||||||
|
dialogProps={{channel}}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.delete'
|
||||||
|
defaultMessage='Delete {term}...'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ToggleModalButton>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.showManagementOptions(channel, isAdmin, isSystemAdmin)) {
|
||||||
|
dropdownContents.push(
|
||||||
|
<li
|
||||||
|
key='set_channel_header'
|
||||||
|
role='presentation'
|
||||||
|
>
|
||||||
|
<ToggleModalButton
|
||||||
|
role='menuitem'
|
||||||
|
dialogType={EditChannelHeaderModal}
|
||||||
|
dialogProps={{channel}}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.setHeader'
|
||||||
|
defaultMessage='Set {term} Header...'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ToggleModalButton>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
|
dropdownContents.push(
|
||||||
|
<li
|
||||||
|
key='set_channel_purpose'
|
||||||
|
role='presentation'
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={() => this.setState({showEditChannelPurposeModal: true})}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.setPurpose'
|
||||||
|
defaultMessage='Set {term} Purpose...'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
dropdownContents.push(
|
dropdownContents.push(
|
||||||
<li
|
<li
|
||||||
key='rename_channel'
|
key='rename_channel'
|
||||||
@@ -414,27 +472,10 @@ export default class ChannelHeader extends React.Component {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!ChannelStore.isDefault(channel)) {
|
if (!ChannelStore.isDefault(channel)) {
|
||||||
dropdownContents.push(
|
dropdownContents.push(deleteOption);
|
||||||
<li
|
|
||||||
key='delete_channel'
|
|
||||||
role='presentation'
|
|
||||||
>
|
|
||||||
<ToggleModalButton
|
|
||||||
role='menuitem'
|
|
||||||
dialogType={DeleteChannelModal}
|
|
||||||
dialogProps={{channel}}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_header.delete'
|
|
||||||
defaultMessage='Delete {term}...'
|
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ToggleModalButton>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
} else if (this.state.userCount === 1) {
|
||||||
|
dropdownContents.push(deleteOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
const canLeave = channel.type === Constants.PRIVATE_CHANNEL ? this.state.userCount > 1 : true;
|
const canLeave = channel.type === Constants.PRIVATE_CHANNEL ? this.state.userCount > 1 : true;
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ import LoadingScreen from './loading_screen.jsx';
|
|||||||
import NewChannelFlow from './new_channel_flow.jsx';
|
import NewChannelFlow from './new_channel_flow.jsx';
|
||||||
|
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
|
import UserStore from 'stores/user_store.jsx';
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
|
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
|
import Constants from 'utils/constants.jsx';
|
||||||
import * as AsyncClient from 'utils/async_client.jsx';
|
import * as AsyncClient from 'utils/async_client.jsx';
|
||||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||||
|
|
||||||
@@ -132,6 +135,41 @@ export default class MoreChannels extends React.Component {
|
|||||||
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
|
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let createNewChannelButton = (
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='btn btn-primary channel-create-btn'
|
||||||
|
onClick={this.handleNewChannel}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='more_channels.create'
|
||||||
|
defaultMessage='Create New Channel'
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
let createChannelHelpText = (
|
||||||
|
<p className='secondary-message'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='more_channels.createClick'
|
||||||
|
defaultMessage="Click 'Create New Channel' to make a new one"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
|
||||||
|
const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
||||||
|
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||||
|
|
||||||
|
if (global.window.mm_license.IsLicensed === 'true') {
|
||||||
|
if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
createNewChannelButton = null;
|
||||||
|
createChannelHelpText = null;
|
||||||
|
} else if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
createNewChannelButton = null;
|
||||||
|
createChannelHelpText = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var moreChannels;
|
var moreChannels;
|
||||||
|
|
||||||
if (this.state.channels != null) {
|
if (this.state.channels != null) {
|
||||||
@@ -153,12 +191,7 @@ export default class MoreChannels extends React.Component {
|
|||||||
defaultMessage='No more channels to join'
|
defaultMessage='No more channels to join'
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p className='secondary-message'>
|
{createChannelHelpText}
|
||||||
<FormattedMessage
|
|
||||||
id='more_channels.createClick'
|
|
||||||
defaultMessage="Click 'Create New Channel' to make a new one"
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -195,16 +228,7 @@ export default class MoreChannels extends React.Component {
|
|||||||
defaultMessage='More Channels'
|
defaultMessage='More Channels'
|
||||||
/>
|
/>
|
||||||
</h4>
|
</h4>
|
||||||
<button
|
{createNewChannelButton}
|
||||||
type='button'
|
|
||||||
className='btn btn-primary channel-create-btn'
|
|
||||||
onClick={this.handleNewChannel}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='more_channels.create'
|
|
||||||
defaultMessage='Create New Channel'
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<NewChannelFlow
|
<NewChannelFlow
|
||||||
show={this.state.showNewChannelModal}
|
show={this.state.showNewChannelModal}
|
||||||
channelType={this.state.channelType}
|
channelType={this.state.channelType}
|
||||||
|
|||||||
@@ -122,10 +122,10 @@ export default class NavbarDropdown extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (global.window.mm_license.IsLicensed === 'true') {
|
if (global.window.mm_license.IsLicensed === 'true') {
|
||||||
if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_SYSTEM_ADMIN && !isSystemAdmin) {
|
if (global.window.mm_config.RestrictTeamInvite === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
teamLink = null;
|
teamLink = null;
|
||||||
inviteLink = null;
|
inviteLink = null;
|
||||||
} else if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_TEAM_ADMIN && !isAdmin) {
|
} else if (global.window.mm_config.RestrictTeamInvite === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
teamLink = null;
|
teamLink = null;
|
||||||
inviteLink = null;
|
inviteLink = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,12 @@
|
|||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
|
|
||||||
|
import UserStore from 'stores/user_store.jsx';
|
||||||
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import PreferenceStore from 'stores/preference_store.jsx';
|
import PreferenceStore from 'stores/preference_store.jsx';
|
||||||
|
|
||||||
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl';
|
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl';
|
||||||
@@ -113,6 +117,47 @@ class NewChannelModal extends React.Component {
|
|||||||
serverError = <div className='form-group has-error'><p className='input__help error'>{this.props.serverError}</p></div>;
|
serverError = <div className='form-group has-error'><p className='input__help error'>{this.props.serverError}</p></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let createPublicChannelLink = (
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={this.props.onTypeSwitched}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_modal.publicChannel1'
|
||||||
|
defaultMessage='Create a public channel'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
|
let createPrivateChannelLink = (
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
onClick={this.props.onTypeSwitched}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_modal.privateGroup2'
|
||||||
|
defaultMessage='Create a private group'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
|
const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
||||||
|
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||||
|
|
||||||
|
if (global.window.mm_license.IsLicensed === 'true') {
|
||||||
|
if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
createPublicChannelLink = null;
|
||||||
|
} else if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
createPublicChannelLink = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
createPrivateChannelLink = null;
|
||||||
|
} else if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
createPrivateChannelLink = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var channelTerm = '';
|
var channelTerm = '';
|
||||||
var channelSwitchText = '';
|
var channelSwitchText = '';
|
||||||
switch (this.props.channelType) {
|
switch (this.props.channelType) {
|
||||||
@@ -129,15 +174,7 @@ class NewChannelModal extends React.Component {
|
|||||||
id='channel_modal.privateGroup1'
|
id='channel_modal.privateGroup1'
|
||||||
defaultMessage='Create a new private group with restricted membership. '
|
defaultMessage='Create a new private group with restricted membership. '
|
||||||
/>
|
/>
|
||||||
<a
|
{createPublicChannelLink}
|
||||||
href='#'
|
|
||||||
onClick={this.props.onTypeSwitched}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_modal.publicChannel1'
|
|
||||||
defaultMessage='Create a public channel'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@@ -154,15 +191,7 @@ class NewChannelModal extends React.Component {
|
|||||||
id='channel_modal.publicChannel2'
|
id='channel_modal.publicChannel2'
|
||||||
defaultMessage='Create a new public channel anyone can join. '
|
defaultMessage='Create a new public channel anyone can join. '
|
||||||
/>
|
/>
|
||||||
<a
|
{createPrivateChannelLink}
|
||||||
href='#'
|
|
||||||
onClick={this.props.onTypeSwitched}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_modal.privateGroup2'
|
|
||||||
defaultMessage='Create a private group'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -682,6 +682,55 @@ export default class Sidebar extends React.Component {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
||||||
|
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||||
|
|
||||||
|
let createPublicChannelIcon = (
|
||||||
|
<OverlayTrigger
|
||||||
|
delayShow={500}
|
||||||
|
placement='top'
|
||||||
|
overlay={createChannelTootlip}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className='add-channel-btn'
|
||||||
|
href='#'
|
||||||
|
onClick={this.showNewChannelModal.bind(this, Constants.OPEN_CHANNEL)}
|
||||||
|
>
|
||||||
|
{'+'}
|
||||||
|
</a>
|
||||||
|
</OverlayTrigger>
|
||||||
|
);
|
||||||
|
|
||||||
|
let createPrivateChannelIcon = (
|
||||||
|
<OverlayTrigger
|
||||||
|
delayShow={500}
|
||||||
|
placement='top'
|
||||||
|
overlay={createGroupTootlip}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className='add-channel-btn'
|
||||||
|
href='#'
|
||||||
|
onClick={this.showNewChannelModal.bind(this, Constants.PRIVATE_CHANNEL)}
|
||||||
|
>
|
||||||
|
{'+'}
|
||||||
|
</a>
|
||||||
|
</OverlayTrigger>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (global.window.mm_license.IsLicensed === 'true') {
|
||||||
|
if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
createPublicChannelIcon = null;
|
||||||
|
} else if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
createPublicChannelIcon = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
createPrivateChannelIcon = null;
|
||||||
|
} else if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
createPrivateChannelIcon = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='sidebar--left'
|
className='sidebar--left'
|
||||||
@@ -728,19 +777,7 @@ export default class Sidebar extends React.Component {
|
|||||||
id='sidebar.channels'
|
id='sidebar.channels'
|
||||||
defaultMessage='Channels'
|
defaultMessage='Channels'
|
||||||
/>
|
/>
|
||||||
<OverlayTrigger
|
{createPublicChannelIcon}
|
||||||
delayShow={500}
|
|
||||||
placement='top'
|
|
||||||
overlay={createChannelTootlip}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
className='add-channel-btn'
|
|
||||||
href='#'
|
|
||||||
onClick={this.showNewChannelModal.bind(this, 'O')}
|
|
||||||
>
|
|
||||||
{'+'}
|
|
||||||
</a>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</h4>
|
</h4>
|
||||||
</li>
|
</li>
|
||||||
{publicChannelItems}
|
{publicChannelItems}
|
||||||
@@ -765,19 +802,7 @@ export default class Sidebar extends React.Component {
|
|||||||
id='sidebar.pg'
|
id='sidebar.pg'
|
||||||
defaultMessage='Private Groups'
|
defaultMessage='Private Groups'
|
||||||
/>
|
/>
|
||||||
<OverlayTrigger
|
{createPrivateChannelIcon}
|
||||||
delayShow={500}
|
|
||||||
placement='top'
|
|
||||||
overlay={createGroupTootlip}
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
className='add-channel-btn'
|
|
||||||
href='#'
|
|
||||||
onClick={this.showNewChannelModal.bind(this, 'P')}
|
|
||||||
>
|
|
||||||
{'+'}
|
|
||||||
</a>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</h4>
|
</h4>
|
||||||
</li>
|
</li>
|
||||||
{privateChannelItems}
|
{privateChannelItems}
|
||||||
|
|||||||
@@ -186,10 +186,10 @@ export default class SidebarRightMenu extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (global.window.mm_license.IsLicensed === 'true') {
|
if (global.window.mm_license.IsLicensed === 'true') {
|
||||||
if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_SYSTEM_ADMIN && !isSystemAdmin) {
|
if (global.window.mm_config.RestrictTeamInvite === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
teamLink = null;
|
teamLink = null;
|
||||||
inviteLink = null;
|
inviteLink = null;
|
||||||
} else if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_TEAM_ADMIN && !isAdmin) {
|
} else if (global.window.mm_config.RestrictTeamInvite === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
teamLink = null;
|
teamLink = null;
|
||||||
inviteLink = null;
|
inviteLink = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export default class TutorialIntroScreens extends React.Component {
|
|||||||
let inviteModalLink;
|
let inviteModalLink;
|
||||||
let inviteText;
|
let inviteText;
|
||||||
|
|
||||||
if (global.window.mm_license.IsLicensed !== 'true' || global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_ALL) {
|
if (global.window.mm_license.IsLicensed !== 'true' || global.window.mm_config.RestrictTeamInvite === Constants.PERMISSIONS_ALL) {
|
||||||
if (team.type === Constants.INVITE_TEAM) {
|
if (team.type === Constants.INVITE_TEAM) {
|
||||||
inviteModalLink = (
|
inviteModalLink = (
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -233,11 +233,15 @@
|
|||||||
"admin.general.localization.serverLocaleTitle": "Default Server Language:",
|
"admin.general.localization.serverLocaleTitle": "Default Server Language:",
|
||||||
"admin.general.log": "Logging",
|
"admin.general.log": "Logging",
|
||||||
"admin.general.policy": "Policy",
|
"admin.general.policy": "Policy",
|
||||||
"admin.general.policy.teamInviteAdmin": "Team and System Admins",
|
"admin.general.policy.permissionsAll": "All team members",
|
||||||
"admin.general.policy.teamInviteAll": "All team members",
|
"admin.general.policy.permissionsAdmin": "Team and System Admins",
|
||||||
"admin.general.policy.teamInviteDescription": "Selecting \"All team members\" allows any team member to invite others using an email invitation or team invite link.<br/><br/>Selecting \"Team and System Admins\" hides the email invitation and team invite link in the Main Menu from users who are not Team or System Admins. Note: If \"Get Team Invite Link\" is used to share a link, it will need to be regenerated after the desired users joined the team.<br/><br/>Selecting \"System Admins\" hides the email invitation and team invite link in the Main Menu from users who are not System Admins. Note: If \"Get Team Invite Link\" is used to share a link, it will need to be regenerated after the desired users joined the team.",
|
"admin.general.policy.permissionsSystemAdmin": "System Admins",
|
||||||
"admin.general.policy.teamInviteSystemAdmin": "System Admins",
|
|
||||||
"admin.general.policy.teamInviteTitle": "Enable sending team invites from:",
|
"admin.general.policy.teamInviteTitle": "Enable sending team invites from:",
|
||||||
|
"admin.general.policy.teamInviteDescription": "Selecting \"All team members\" allows any team member to invite others using an email invitation or team invite link.<br/><br/>Selecting \"Team and System Admins\" hides the email invitation and team invite link in the Main Menu from users who are not Team or System Admins. Note: If \"Get Team Invite Link\" is used to share a link, it will need to be regenerated after the desired users joined the team.<br/><br/>Selecting \"System Admins\" hides the email invitation and team invite link in the Main Menu from users who are not System Admins. Note: If \"Get Team Invite Link\" is used to share a link, it will need to be regenerated after the desired users joined the team.",
|
||||||
|
"admin.general.policy.restrictPublicChannelManagementTitle": "Enable public channel management permissions for:",
|
||||||
|
"admin.general.policy.restrictPublicChannelManagementDescription": "Selecting \"All team members\" allows any team members to create, delete, rename, and set the header or purpose for public channels.<br/><br/>Selecting \"Team and System Admins\" restricts channel management permissions for public channels to Team and System Admins, including creating, deleting, renaming, and setting the channel header or purpose.<br/><br/>Selecting \"System Admins\" restricts channel management permissions for public channels to System Admins, including creating, deleting, renaming, and setting the channel header or purpose.",
|
||||||
|
"admin.general.policy.restrictPrivateChannelManagementTitle": "Enable private group management permissions for:",
|
||||||
|
"admin.general.policy.restrictPrivateChannelManagementDescription": "Selecting \"All team members\" allows any team members to create, delete, rename, and set the header or purpose for private groups.<br/><br/>Selecting \"Team and System Admins\" restricts group management permissions for private groups to Team and System Admins, including creating, deleting, renaming, and setting the group header or purpose.<br/><br/>Selecting \"System Admins\" restricts group management permissions for private groups to System Admins, including creating, deleting, renaming, and setting the group header or purpose.",
|
||||||
"admin.general.privacy": "Privacy",
|
"admin.general.privacy": "Privacy",
|
||||||
"admin.general.usersAndTeams": "Users and Teams",
|
"admin.general.usersAndTeams": "Users and Teams",
|
||||||
"admin.gitab.clientSecretDescription": "Obtain this value via the instructions above for logging into GitLab.",
|
"admin.gitab.clientSecretDescription": "Obtain this value via the instructions above for logging into GitLab.",
|
||||||
|
|||||||
@@ -53,54 +53,70 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
this.extraInfos = {};
|
this.extraInfos = {};
|
||||||
this.unreadCounts = {};
|
this.unreadCounts = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
get POST_MODE_CHANNEL() {
|
get POST_MODE_CHANNEL() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
get POST_MODE_FOCUS() {
|
get POST_MODE_FOCUS() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
emitChange() {
|
emitChange() {
|
||||||
this.emit(CHANGE_EVENT);
|
this.emit(CHANGE_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
addChangeListener(callback) {
|
addChangeListener(callback) {
|
||||||
this.on(CHANGE_EVENT, callback);
|
this.on(CHANGE_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeChangeListener(callback) {
|
removeChangeListener(callback) {
|
||||||
this.removeListener(CHANGE_EVENT, callback);
|
this.removeListener(CHANGE_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitMoreChange() {
|
emitMoreChange() {
|
||||||
this.emit(MORE_CHANGE_EVENT);
|
this.emit(MORE_CHANGE_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
addMoreChangeListener(callback) {
|
addMoreChangeListener(callback) {
|
||||||
this.on(MORE_CHANGE_EVENT, callback);
|
this.on(MORE_CHANGE_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeMoreChangeListener(callback) {
|
removeMoreChangeListener(callback) {
|
||||||
this.removeListener(MORE_CHANGE_EVENT, callback);
|
this.removeListener(MORE_CHANGE_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
emitExtraInfoChange() {
|
emitExtraInfoChange() {
|
||||||
this.emit(EXTRA_INFO_EVENT);
|
this.emit(EXTRA_INFO_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
addExtraInfoChangeListener(callback) {
|
addExtraInfoChangeListener(callback) {
|
||||||
this.on(EXTRA_INFO_EVENT, callback);
|
this.on(EXTRA_INFO_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeExtraInfoChangeListener(callback) {
|
removeExtraInfoChangeListener(callback) {
|
||||||
this.removeListener(EXTRA_INFO_EVENT, callback);
|
this.removeListener(EXTRA_INFO_EVENT, callback);
|
||||||
}
|
}
|
||||||
emitLeave(id) {
|
emitLeave(id) {
|
||||||
this.emit(LEAVE_EVENT, id);
|
this.emit(LEAVE_EVENT, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
addLeaveListener(callback) {
|
addLeaveListener(callback) {
|
||||||
this.on(LEAVE_EVENT, callback);
|
this.on(LEAVE_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeLeaveListener(callback) {
|
removeLeaveListener(callback) {
|
||||||
this.removeListener(LEAVE_EVENT, callback);
|
this.removeListener(LEAVE_EVENT, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
findFirstBy(field, value) {
|
findFirstBy(field, value) {
|
||||||
return this.doFindFirst(field, value, this.getChannels());
|
return this.doFindFirst(field, value, this.getChannels());
|
||||||
}
|
}
|
||||||
|
|
||||||
findFirstMoreBy(field, value) {
|
findFirstMoreBy(field, value) {
|
||||||
return this.doFindFirst(field, value, this.getMoreChannels());
|
return this.doFindFirst(field, value, this.getMoreChannels());
|
||||||
}
|
}
|
||||||
|
|
||||||
doFindFirst(field, value, channels) {
|
doFindFirst(field, value, channels) {
|
||||||
for (var i = 0; i < channels.length; i++) {
|
for (var i = 0; i < channels.length; i++) {
|
||||||
if (channels[i][field] === value) {
|
if (channels[i][field] === value) {
|
||||||
@@ -110,33 +126,43 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(id) {
|
get(id) {
|
||||||
return this.findFirstBy('id', id);
|
return this.findFirstBy('id', id);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMember(id) {
|
getMember(id) {
|
||||||
return this.getAllMembers()[id];
|
return this.getAllMembers()[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
getByName(name) {
|
getByName(name) {
|
||||||
return this.findFirstBy('name', name);
|
return this.findFirstBy('name', name);
|
||||||
}
|
}
|
||||||
|
|
||||||
getByDisplayName(displayName) {
|
getByDisplayName(displayName) {
|
||||||
return this.findFirstBy('display_name', displayName);
|
return this.findFirstBy('display_name', displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMoreByName(name) {
|
getMoreByName(name) {
|
||||||
return this.findFirstMoreBy('name', name);
|
return this.findFirstMoreBy('name', name);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAll() {
|
getAll() {
|
||||||
return this.getChannels();
|
return this.getChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllMembers() {
|
getAllMembers() {
|
||||||
return this.getChannelMembers();
|
return this.getChannelMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
getMoreAll() {
|
getMoreAll() {
|
||||||
return this.getMoreChannels();
|
return this.getMoreChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentId(id) {
|
setCurrentId(id) {
|
||||||
this.currentId = id;
|
this.currentId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetCounts(id) {
|
resetCounts(id) {
|
||||||
const cm = this.channelMembers;
|
const cm = this.channelMembers;
|
||||||
for (var cmid in cm) {
|
for (var cmid in cm) {
|
||||||
@@ -151,9 +177,11 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentId() {
|
getCurrentId() {
|
||||||
return this.currentId;
|
return this.currentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrent() {
|
getCurrent() {
|
||||||
var currentId = this.getCurrentId();
|
var currentId = this.getCurrentId();
|
||||||
|
|
||||||
@@ -163,6 +191,7 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentMember() {
|
getCurrentMember() {
|
||||||
var currentId = this.getCurrentId();
|
var currentId = this.getCurrentId();
|
||||||
|
|
||||||
@@ -172,15 +201,18 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
setChannelMember(member) {
|
setChannelMember(member) {
|
||||||
var members = this.getChannelMembers();
|
var members = this.getChannelMembers();
|
||||||
members[member.channel_id] = member;
|
members[member.channel_id] = member;
|
||||||
this.storeChannelMembers(members);
|
this.storeChannelMembers(members);
|
||||||
this.emitChange();
|
this.emitChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentExtraInfo() {
|
getCurrentExtraInfo() {
|
||||||
return this.getExtraInfo(this.getCurrentId());
|
return this.getExtraInfo(this.getCurrentId());
|
||||||
}
|
}
|
||||||
|
|
||||||
getExtraInfo(channelId) {
|
getExtraInfo(channelId) {
|
||||||
var extra = null;
|
var extra = null;
|
||||||
|
|
||||||
@@ -197,6 +229,7 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
|
|
||||||
return extra;
|
return extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStoreChannel(channel) {
|
pStoreChannel(channel) {
|
||||||
var channels = this.getChannels();
|
var channels = this.getChannels();
|
||||||
var found;
|
var found;
|
||||||
@@ -220,35 +253,45 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
channels.sort(Utils.sortByDisplayName);
|
channels.sort(Utils.sortByDisplayName);
|
||||||
this.storeChannels(channels);
|
this.storeChannels(channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
storeChannels(channels) {
|
storeChannels(channels) {
|
||||||
this.channels = channels;
|
this.channels = channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
getChannels() {
|
getChannels() {
|
||||||
return this.channels;
|
return this.channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStoreChannelMember(channelMember) {
|
pStoreChannelMember(channelMember) {
|
||||||
var members = this.getChannelMembers();
|
var members = this.getChannelMembers();
|
||||||
members[channelMember.channel_id] = channelMember;
|
members[channelMember.channel_id] = channelMember;
|
||||||
this.storeChannelMembers(members);
|
this.storeChannelMembers(members);
|
||||||
}
|
}
|
||||||
|
|
||||||
storeChannelMembers(channelMembers) {
|
storeChannelMembers(channelMembers) {
|
||||||
this.channelMembers = channelMembers;
|
this.channelMembers = channelMembers;
|
||||||
}
|
}
|
||||||
|
|
||||||
getChannelMembers() {
|
getChannelMembers() {
|
||||||
return this.channelMembers;
|
return this.channelMembers;
|
||||||
}
|
}
|
||||||
|
|
||||||
storeMoreChannels(channels) {
|
storeMoreChannels(channels) {
|
||||||
this.moreChannels = channels;
|
this.moreChannels = channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMoreChannels() {
|
getMoreChannels() {
|
||||||
return this.moreChannels;
|
return this.moreChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
storeExtraInfos(extraInfos) {
|
storeExtraInfos(extraInfos) {
|
||||||
this.extraInfos = extraInfos;
|
this.extraInfos = extraInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
getExtraInfos() {
|
getExtraInfos() {
|
||||||
return this.extraInfos;
|
return this.extraInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
isDefault(channel) {
|
isDefault(channel) {
|
||||||
return channel.name === Constants.DEFAULT_CHANNEL;
|
return channel.name === Constants.DEFAULT_CHANNEL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,9 +114,9 @@ export function createDefaultIntroMessage(channel) {
|
|||||||
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||||
|
|
||||||
if (global.window.mm_license.IsLicensed === 'true') {
|
if (global.window.mm_license.IsLicensed === 'true') {
|
||||||
if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_SYSTEM_ADMIN && !isSystemAdmin) {
|
if (global.window.mm_config.RestrictTeamInvite === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
inviteModalLink = null;
|
inviteModalLink = null;
|
||||||
} else if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_TEAM_ADMIN && !isAdmin) {
|
} else if (global.window.mm_config.RestrictTeamInvite === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
inviteModalLink = null;
|
inviteModalLink = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -762,7 +762,7 @@ export default {
|
|||||||
POST_COLLAPSE_TIMEOUT: 1000 * 60 * 5, // five minutes
|
POST_COLLAPSE_TIMEOUT: 1000 * 60 * 5, // five minutes
|
||||||
LICENSE_EXPIRY_NOTIFICATION: 1000 * 60 * 60 * 24 * 15, // 15 days
|
LICENSE_EXPIRY_NOTIFICATION: 1000 * 60 * 60 * 24 * 15, // 15 days
|
||||||
LICENSE_GRACE_PERIOD: 1000 * 60 * 60 * 24 * 15, // 15 days
|
LICENSE_GRACE_PERIOD: 1000 * 60 * 60 * 24 * 15, // 15 days
|
||||||
TEAM_INVITE_ALL: 'all',
|
PERMISSIONS_ALL: 'all',
|
||||||
TEAM_INVITE_TEAM_ADMIN: 'team_admin',
|
PERMISSIONS_TEAM_ADMIN: 'team_admin',
|
||||||
TEAM_INVITE_SYSTEM_ADMIN: 'system_admin'
|
PERMISSIONS_SYSTEM_ADMIN: 'system_admin'
|
||||||
};
|
};
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user