Modifying permissions system. (#3897)

This commit is contained in:
Christopher Speller
2016-09-13 12:42:48 -04:00
committed by Joram Wilander
parent 05af5d14b8
commit 1e7985a87a
45 changed files with 1102 additions and 605 deletions

View File

@@ -25,18 +25,18 @@ import (
func InitAdmin() {
l4g.Debug(utils.T("api.admin.init.debug"))
BaseRoutes.Admin.Handle("/logs", ApiUserRequired(getLogs)).Methods("GET")
BaseRoutes.Admin.Handle("/audits", ApiUserRequired(getAllAudits)).Methods("GET")
BaseRoutes.Admin.Handle("/config", ApiUserRequired(getConfig)).Methods("GET")
BaseRoutes.Admin.Handle("/save_config", ApiUserRequired(saveConfig)).Methods("POST")
BaseRoutes.Admin.Handle("/reload_config", ApiUserRequired(reloadConfig)).Methods("GET")
BaseRoutes.Admin.Handle("/test_email", ApiUserRequired(testEmail)).Methods("POST")
BaseRoutes.Admin.Handle("/recycle_db_conn", ApiUserRequired(recycleDatabaseConnection)).Methods("GET")
BaseRoutes.Admin.Handle("/analytics/{id:[A-Za-z0-9]+}/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET")
BaseRoutes.Admin.Handle("/analytics/{name:[A-Za-z0-9_]+}", ApiUserRequired(getAnalytics)).Methods("GET")
BaseRoutes.Admin.Handle("/save_compliance_report", ApiUserRequired(saveComplianceReport)).Methods("POST")
BaseRoutes.Admin.Handle("/compliance_reports", ApiUserRequired(getComplianceReports)).Methods("GET")
BaseRoutes.Admin.Handle("/download_compliance_report/{id:[A-Za-z0-9]+}", ApiUserRequiredTrustRequester(downloadComplianceReport)).Methods("GET")
BaseRoutes.Admin.Handle("/logs", ApiAdminSystemRequired(getLogs)).Methods("GET")
BaseRoutes.Admin.Handle("/audits", ApiAdminSystemRequired(getAllAudits)).Methods("GET")
BaseRoutes.Admin.Handle("/config", ApiAdminSystemRequired(getConfig)).Methods("GET")
BaseRoutes.Admin.Handle("/save_config", ApiAdminSystemRequired(saveConfig)).Methods("POST")
BaseRoutes.Admin.Handle("/reload_config", ApiAdminSystemRequired(reloadConfig)).Methods("GET")
BaseRoutes.Admin.Handle("/test_email", ApiAdminSystemRequired(testEmail)).Methods("POST")
BaseRoutes.Admin.Handle("/recycle_db_conn", ApiAdminSystemRequired(recycleDatabaseConnection)).Methods("GET")
BaseRoutes.Admin.Handle("/analytics/{id:[A-Za-z0-9]+}/{name:[A-Za-z0-9_]+}", ApiAdminSystemRequired(getAnalytics)).Methods("GET")
BaseRoutes.Admin.Handle("/analytics/{name:[A-Za-z0-9_]+}", ApiAdminSystemRequired(getAnalytics)).Methods("GET")
BaseRoutes.Admin.Handle("/save_compliance_report", ApiAdminSystemRequired(saveComplianceReport)).Methods("POST")
BaseRoutes.Admin.Handle("/compliance_reports", ApiAdminSystemRequired(getComplianceReports)).Methods("GET")
BaseRoutes.Admin.Handle("/download_compliance_report/{id:[A-Za-z0-9]+}", ApiAdminSystemRequiredTrustRequester(downloadComplianceReport)).Methods("GET")
BaseRoutes.Admin.Handle("/upload_brand_image", ApiAdminSystemRequired(uploadBrandImage)).Methods("POST")
BaseRoutes.Admin.Handle("/get_brand_image", ApiAppHandlerTrustRequester(getBrandImage)).Methods("GET")
BaseRoutes.Admin.Handle("/reset_mfa", ApiAdminSystemRequired(adminResetMfa)).Methods("POST")
@@ -52,11 +52,6 @@ func InitAdmin() {
}
func getLogs(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getLogs") {
return
}
lines, err := GetLogs()
if err != nil {
c.Err = err
@@ -99,11 +94,6 @@ func GetLogs() ([]string, *model.AppError) {
}
func getClusterStatus(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getClusterStatus") {
return
}
infos := make([]*model.ClusterInfo, 0)
if einterfaces.GetClusterInterface() != nil {
infos = einterfaces.GetClusterInterface().GetClusterInfos()
@@ -113,11 +103,6 @@ func getClusterStatus(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getAllAudits(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getAllAudits") {
return
}
if result := <-Srv.Store.Audit().Get("", 200); result.Err != nil {
c.Err = result.Err
return
@@ -139,10 +124,6 @@ func getAllAudits(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getConfig(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getConfig") {
return
}
json := utils.Cfg.ToJson()
cfg := model.ConfigFromJson(strings.NewReader(json))
@@ -153,10 +134,6 @@ func getConfig(c *Context, w http.ResponseWriter, r *http.Request) {
}
func reloadConfig(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("reloadConfig") {
return
}
utils.LoadConfig(utils.CfgFileName)
// start/restart email batching job if necessary
@@ -167,10 +144,6 @@ func reloadConfig(c *Context, w http.ResponseWriter, r *http.Request) {
}
func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getConfig") {
return
}
cfg := model.ConfigFromJson(r.Body)
if cfg == nil {
c.SetInvalidParam("saveConfig", "config")
@@ -219,10 +192,6 @@ func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) {
}
func recycleDatabaseConnection(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("recycleDatabaseConnection") {
return
}
oldStore := Srv.Store
l4g.Warn(utils.T("api.admin.recycle_db_start.warn"))
@@ -238,10 +207,6 @@ func recycleDatabaseConnection(c *Context, w http.ResponseWriter, r *http.Reques
}
func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("testEmail") {
return
}
cfg := model.ConfigFromJson(r.Body)
if cfg == nil {
c.SetInvalidParam("testEmail", "config")
@@ -282,10 +247,6 @@ func testEmail(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getComplianceReports(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getComplianceReports") {
return
}
if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed || !*utils.License.Features.Compliance {
c.Err = model.NewLocAppError("getComplianceReports", "ent.compliance.licence_disable.app_error", nil, "")
return
@@ -301,10 +262,6 @@ func getComplianceReports(c *Context, w http.ResponseWriter, r *http.Request) {
}
func saveComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getComplianceReports") {
return
}
if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed || !*utils.License.Features.Compliance || einterfaces.GetComplianceInterface() == nil {
c.Err = model.NewLocAppError("saveComplianceReport", "ent.compliance.licence_disable.app_error", nil, "")
return
@@ -331,10 +288,6 @@ func saveComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) {
}
func downloadComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("downloadComplianceReport") {
return
}
if !*utils.Cfg.ComplianceSettings.Enable || !utils.IsLicensed || !*utils.License.Features.Compliance || einterfaces.GetComplianceInterface() == nil {
c.Err = model.NewLocAppError("downloadComplianceReport", "ent.compliance.licence_disable.app_error", nil, "")
return
@@ -380,10 +333,6 @@ func downloadComplianceReport(c *Context, w http.ResponseWriter, r *http.Request
}
func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasSystemAdminPermissions("getAnalytics") {
return
}
params := mux.Vars(r)
teamId := params["id"]
name := params["name"]

View File

@@ -91,7 +91,7 @@ func (me *TestHelper) InitSystemAdmin() *TestHelper {
c := &Context{}
c.RequestId = model.NewId()
c.IpAddress = "cmd_line"
UpdateUserRoles(c, me.SystemAdminUser, model.ROLE_SYSTEM_ADMIN)
UpdateUserRoles(c, me.SystemAdminUser, model.ROLE_SYSTEM_USER.Id+" "+model.ROLE_SYSTEM_ADMIN.Id)
me.SystemAdminUser.Password = "Password1"
me.LoginSystemAdmin()
me.SystemAdminChannel = me.CreateChannel(me.SystemAdminClient, me.SystemAdminTeam)
@@ -157,13 +157,15 @@ func LinkUserToTeam(user *model.User, team *model.Team) {
func UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.ROLE_TEAM_ADMIN}
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.ROLE_TEAM_USER.Id + " " + model.ROLE_TEAM_ADMIN.Id}
if tmr := <-Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
utils.EnableDebugLogForTest()
l4g.Error(tmr.Err.Error())
l4g.Close()
time.Sleep(time.Second)
panic(tmr.Err)
}
utils.EnableDebugLogForTest()
}
func (me *TestHelper) CreateChannel(client *model.Client, team *model.Team) *model.Channel {

149
api/authorization.go Normal file
View File

@@ -0,0 +1,149 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"net/http"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/model"
)
func HasPermissionToContext(c *Context, permission *model.Permission) bool {
userRoles := c.Session.GetUserRoles()
if !CheckIfRolesGrantPermission(userRoles, permission.Id) {
c.Err = model.NewLocAppError("HasPermissionToContext", "api.context.permissions.app_error", nil, "userId="+c.Session.UserId+", teamId="+c.TeamId+" permission="+permission.Id+" "+model.RoleIdsToString(userRoles))
c.Err.StatusCode = http.StatusForbidden
return false
}
return true
}
func HasPermissionTo(user *model.User, permission *model.Permission) bool {
roles := user.GetRoles()
return CheckIfRolesGrantPermission(roles, permission.Id)
}
func HasPermissionToCurrentTeamContext(c *Context, permission *model.Permission) bool {
return HasPermissionToTeamContext(c, c.TeamId, permission)
}
func HasPermissionToTeamContext(c *Context, teamId string, permission *model.Permission) bool {
teamMember := c.Session.GetTeamByTeamId(teamId)
if teamMember != nil {
roles := teamMember.GetRoles()
if CheckIfRolesGrantPermission(roles, permission.Id) {
return true
}
}
if HasPermissionToContext(c, permission) {
return true
}
c.Err = model.NewLocAppError("HasPermissionToTeamContext", "api.context.permissions.app_error", nil, "userId="+c.Session.UserId+", teamId="+c.TeamId+" permission="+permission.Id)
c.Err.StatusCode = http.StatusForbidden
return false
}
func HasPermissionToTeam(user *model.User, teamMember *model.TeamMember, permission *model.Permission) bool {
if teamMember == nil {
return false
}
roles := teamMember.GetRoles()
if CheckIfRolesGrantPermission(roles, permission.Id) {
return true
}
return HasPermissionTo(user, permission)
}
func HasPermissionToChannelContext(c *Context, channelId string, permission *model.Permission) bool {
cmc := Srv.Store.Channel().GetMember(channelId, c.Session.UserId)
var channelRoles []string
if cmcresult := <-cmc; cmcresult.Err == nil {
channelMember := cmcresult.Data.(model.ChannelMember)
channelRoles = channelMember.GetRoles()
if CheckIfRolesGrantPermission(channelRoles, permission.Id) {
return true
}
}
cc := Srv.Store.Channel().Get(channelId)
if ccresult := <-cc; ccresult.Err == nil {
channel := ccresult.Data.(*model.Channel)
if teamMember := c.Session.GetTeamByTeamId(channel.TeamId); teamMember != nil {
roles := teamMember.GetRoles()
if CheckIfRolesGrantPermission(roles, permission.Id) {
return true
}
}
}
if HasPermissionToContext(c, permission) {
return true
}
c.Err = model.NewLocAppError("HasPermissionToChannelContext", "api.context.permissions.app_error", nil, "userId="+c.Session.UserId+", "+"permission="+permission.Id+" channelRoles="+model.RoleIdsToString(channelRoles))
c.Err.StatusCode = http.StatusForbidden
return false
}
func HasPermissionToChannel(user *model.User, teamMember *model.TeamMember, channelMember *model.ChannelMember, permission *model.Permission) bool {
if channelMember == nil {
return false
}
roles := channelMember.GetRoles()
if CheckIfRolesGrantPermission(roles, permission.Id) {
return true
}
return HasPermissionToTeam(user, teamMember, permission)
}
func HasPermissionToUser(c *Context, userId string) bool {
// You are the user (users autmaticly have permissions to themselves)
if c.Session.UserId == userId {
return true
}
// You have permission
if HasPermissionToContext(c, model.PERMISSION_EDIT_OTHER_USERS) {
return true
}
c.Err = model.NewLocAppError("HasPermissionToUser", "api.context.permissions.app_error", nil, "userId="+userId)
c.Err.StatusCode = http.StatusForbidden
return false
}
func CheckIfRolesGrantPermission(roles []string, permissionId string) bool {
for _, roleId := range roles {
if role, ok := model.BuiltInRoles[roleId]; !ok {
l4g.Debug("Bad role in system " + roleId)
return false
} else {
permissions := role.Permissions
for _, permission := range permissions {
if permission == permissionId {
return true
}
}
}
}
return false
}

36
api/authorization_test.go Normal file
View File

@@ -0,0 +1,36 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package api
import (
"testing"
"github.com/mattermost/platform/model"
)
func TestCheckIfRolesGrantPermission(t *testing.T) {
Setup()
cases := []struct {
roles []string
permissionId string
shouldGrant bool
}{
{[]string{model.ROLE_SYSTEM_ADMIN.Id}, model.ROLE_SYSTEM_ADMIN.Permissions[0], true},
{[]string{model.ROLE_SYSTEM_ADMIN.Id}, "non-existant-permission", false},
{[]string{model.ROLE_CHANNEL_USER.Id}, model.ROLE_CHANNEL_USER.Permissions[0], true},
{[]string{model.ROLE_CHANNEL_USER.Id}, model.PERMISSION_MANAGE_SYSTEM.Id, false},
{[]string{model.ROLE_SYSTEM_ADMIN.Id, model.ROLE_CHANNEL_USER.Id}, model.PERMISSION_MANAGE_SYSTEM.Id, true},
{[]string{model.ROLE_CHANNEL_USER.Id, model.ROLE_SYSTEM_ADMIN.Id}, model.PERMISSION_MANAGE_SYSTEM.Id, true},
{[]string{model.ROLE_TEAM_USER.Id, model.ROLE_TEAM_ADMIN.Id}, model.PERMISSION_MANAGE_SLASH_COMMANDS.Id, true},
{[]string{model.ROLE_TEAM_ADMIN.Id, model.ROLE_TEAM_USER.Id}, model.PERMISSION_MANAGE_SLASH_COMMANDS.Id, true},
}
for testnum, testcase := range cases {
if CheckIfRolesGrantPermission(testcase.roles, testcase.permissionId) != testcase.shouldGrant {
t.Fatal("Failed test case ", testnum)
}
}
}

View File

@@ -60,15 +60,6 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
channel.TeamId = c.TeamId
}
if err := CanManageChannel(c, channel); err != nil {
c.Err = err
return
}
if !c.HasPermissionsToTeam(channel.TeamId, "createChannel") {
return
}
if channel.Type == model.CHANNEL_DIRECT {
c.Err = model.NewLocAppError("createDirectChannel", "api.channel.create_channel.direct_channel.app_error", nil, "")
return
@@ -79,6 +70,14 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if channel.Type == model.CHANNEL_OPEN && !HasPermissionToTeamContext(c, channel.TeamId, model.PERMISSION_CREATE_PUBLIC_CHANNEL) {
return
}
if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToTeamContext(c, channel.TeamId, model.PERMISSION_CREATE_PRIVATE_CHANNEL) {
return
}
channel.CreatorId = c.Session.UserId
if sc, err := CreateChannel(c, channel, true); err != nil {
@@ -96,8 +95,12 @@ func CreateChannel(c *Context, channel *model.Channel, addMember bool) (*model.C
sc := result.Data.(*model.Channel)
if addMember {
cm := &model.ChannelMember{ChannelId: sc.Id, UserId: c.Session.UserId,
Roles: model.CHANNEL_ROLE_ADMIN, NotifyProps: model.GetDefaultChannelNotifyProps()}
cm := &model.ChannelMember{
ChannelId: sc.Id,
UserId: c.Session.UserId,
Roles: model.ROLE_CHANNEL_USER.Id + " " + model.ROLE_CHANNEL_ADMIN.Id,
NotifyProps: model.GetDefaultChannelNotifyProps(),
}
if cmresult := <-Srv.Store.Channel().SaveMember(cm); cmresult.Err != nil {
return nil, cmresult.Err
@@ -111,6 +114,9 @@ func CreateChannel(c *Context, channel *model.Channel, addMember bool) (*model.C
}
func createDirectChannel(c *Context, w http.ResponseWriter, r *http.Request) {
if !HasPermissionToContext(c, model.PERMISSION_CREATE_DIRECT_CHANNEL) {
return
}
data := model.MapFromJson(r.Body)
@@ -146,10 +152,12 @@ func CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *mo
cm1 := &model.ChannelMember{
UserId: userId,
NotifyProps: model.GetDefaultChannelNotifyProps(),
Roles: model.ROLE_CHANNEL_USER.Id,
}
cm2 := &model.ChannelMember{
UserId: otherUserId,
NotifyProps: model.GetDefaultChannelNotifyProps(),
Roles: model.ROLE_CHANNEL_USER.Id,
}
if result := <-Srv.Store.Channel().SaveDirectChannel(channel, cm1, cm2); result.Err != nil {
@@ -184,30 +192,16 @@ func CreateDefaultChannels(c *Context, teamId string) ([]*model.Channel, *model.
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, "")
}
}
func CanManageChannel(c *Context, channel *model.Channel) bool {
if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES) {
return false
}
return nil
if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES) {
return false
}
return true
}
func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
@@ -232,12 +226,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
oldChannel := cresult.Data.(*model.Channel)
// Don't need to do anything with channel member, just wanted to confirm it exists
if err := CanManageChannel(c, oldChannel); err != nil {
c.Err = err
return
}
if !c.HasPermissionsToTeam(oldChannel.TeamId, "updateChannel") {
if !CanManageChannel(c, channel) {
return
}
@@ -308,14 +297,10 @@ func updateChannelHeader(c *Context, w http.ResponseWriter, r *http.Request) {
channel := cresult.Data.(*model.Channel)
// 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
if !CanManageChannel(c, channel) {
return
}
if channel.TeamId != "" && !c.HasPermissionsToTeam(channel.TeamId, "updateChannelHeader") {
return
}
oldChannelHeader := channel.Header
channel.Header = channelHeader
@@ -387,12 +372,7 @@ func updateChannelPurpose(c *Context, w http.ResponseWriter, r *http.Request) {
channel := cresult.Data.(*model.Channel)
// 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 !CanManageChannel(c, channel) {
return
}
@@ -411,6 +391,7 @@ func updateChannelPurpose(c *Context, w http.ResponseWriter, r *http.Request) {
func getChannels(c *Context, w http.ResponseWriter, r *http.Request) {
// user is already in the team
// Get's all channels the user is a member of
if result := <-Srv.Store.Channel().GetChannels(c.TeamId, c.Session.UserId); result.Err != nil {
if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
@@ -436,6 +417,9 @@ func getChannels(c *Context, w http.ResponseWriter, r *http.Request) {
func getMoreChannels(c *Context, w http.ResponseWriter, r *http.Request) {
// user is already in the team
if !HasPermissionToTeamContext(c, c.TeamId, model.PERMISSION_LIST_TEAM_CHANNELS) {
return
}
if result := <-Srv.Store.Channel().GetMoreChannels(c.TeamId, c.Session.UserId); result.Err != nil {
c.Err = result.Err
@@ -523,7 +507,7 @@ func joinChannel(c *Context, channelChannel store.StoreChannel, userChannel stor
return nil, channel
}
if !c.HasPermissionsToTeam(channel.TeamId, "join") {
if !HasPermissionToTeamContext(c, channel.TeamId, model.PERMISSION_JOIN_PUBLIC_CHANNELS) {
return c.Err, nil
}
@@ -581,7 +565,12 @@ func AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelM
return &channelMember, nil
}
newMember := &model.ChannelMember{ChannelId: channel.Id, UserId: user.Id, NotifyProps: model.GetDefaultChannelNotifyProps()}
newMember := &model.ChannelMember{
ChannelId: channel.Id,
UserId: user.Id,
NotifyProps: model.GetDefaultChannelNotifyProps(),
Roles: model.ROLE_CHANNEL_USER.Id,
}
if result := <-Srv.Store.Channel().SaveMember(newMember); result.Err != nil {
l4g.Error("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, result.Err)
return nil, model.NewLocAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.app_error", nil, "")
@@ -669,10 +658,6 @@ func leave(c *Context, w http.ResponseWriter, r *http.Request) {
user := uresult.Data.(*model.User)
membersCount := ccmresult.Data.(int64)
if !c.HasPermissionsToTeam(channel.TeamId, "leave") {
return
}
if channel.Type == model.CHANNEL_DIRECT {
c.Err = model.NewLocAppError("leave", "api.channel.leave.direct.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
@@ -746,14 +731,13 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) {
// Allow delete if user is the only member left in channel
if memberCount > 1 {
if err := CanManageChannel(c, channel); err != nil {
c.Err = err
if channel.Type == model.CHANNEL_OPEN && !HasPermissionToTeamContext(c, channel.TeamId, model.PERMISSION_DELETE_PUBLIC_CHANNEL) {
return
}
}
if !c.HasPermissionsToTeam(channel.TeamId, "deleteChannel") {
return
if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToTeamContext(c, channel.TeamId, model.PERMISSION_DELETE_PRIVATE_CHANNEL) {
return
}
}
if channel.DeleteAt > 0 {
@@ -901,7 +885,6 @@ func getChannel(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["channel_id"]
//pchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
cchan := Srv.Store.Channel().Get(id)
cmchan := Srv.Store.Channel().GetMember(id, c.Session.UserId)
@@ -974,24 +957,20 @@ func getChannelExtraInfo(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = ccmresult.Err
return
} else {
member := cmresult.Data.(model.ChannelMember)
//member := cmresult.Data.(model.ChannelMember)
extraMembers := ecmresult.Data.([]model.ExtraMember)
memberCount := ccmresult.Data.(int64)
if len(channel.TeamId) > 0 && !c.HasPermissionsToTeam(channel.TeamId, "getChannelExtraInfo") {
return
}
if !c.HasPermissionsToUser(member.UserId, "getChannelExtraInfo") {
return
}
if channel.DeleteAt > 0 {
c.Err = model.NewLocAppError("getChannelExtraInfo", "api.channel.get_channel_extra_info.deleted.app_error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
}
if !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_READ_CHANNEL) {
return
}
data := model.ChannelExtra{Id: channel.Id, Members: extraMembers, MemberCount: memberCount}
w.Header().Set(model.HEADER_ETAG_SERVER, extraEtag)
w.Write([]byte(data.ToJson()))
@@ -1010,16 +989,9 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
sc := Srv.Store.Channel().Get(id)
ouc := Srv.Store.User().Get(c.Session.UserId)
nuc := Srv.Store.User().Get(userId)
// Only need to be a member of the channel to add a new member
if !c.HasPermissionsToChannel(cchan, "addMember") {
return
}
if nresult := <-nuc; nresult.Err != nil {
c.Err = model.NewLocAppError("addMember", "api.channel.add_member.find_user.app_error", nil, "")
return
@@ -1030,6 +1002,14 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
channel := cresult.Data.(*model.Channel)
nUser := nresult.Data.(*model.User)
if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS) {
return
}
if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS) {
return
}
if oresult := <-ouc; oresult.Err != nil {
c.Err = model.NewLocAppError("addMember", "api.channel.add_member.user_adding.app_error", nil, "")
return
@@ -1082,15 +1062,12 @@ func removeMember(c *Context, w http.ResponseWriter, r *http.Request) {
return
} else {
channel := cresult.Data.(*model.Channel)
removerChannelMember := cmcresult.Data.(model.ChannelMember)
if !c.HasPermissionsToTeam(channel.TeamId, "removeMember") {
if channel.Type == model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS) {
return
}
if !strings.Contains(removerChannelMember.Roles, model.CHANNEL_ROLE_ADMIN) && !c.IsTeamAdmin() {
c.Err = model.NewLocAppError("updateChannel", "api.channel.remove_member.permissions.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
if channel.Type == model.CHANNEL_PRIVATE && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS) {
return
}
@@ -1145,13 +1122,7 @@ func updateNotifyProps(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
if !c.HasPermissionsToUser(userId, "updateNotifyLevel") {
return
}
if !c.HasPermissionsToChannel(cchan, "updateNotifyLevel") {
if !HasPermissionToUser(c, userId) {
return
}

View File

@@ -4,13 +4,14 @@
package api
import (
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
"net/http"
"strings"
"testing"
"time"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
func TestCreateChannel(t *testing.T) {
@@ -100,9 +101,11 @@ func TestCreateChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
utils.IsLicensed = isLicensed
utils.SetDefaultRolesBasedOnConfig()
}()
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
utils.SetDefaultRolesBasedOnConfig()
utils.IsLicensed = true
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
@@ -116,6 +119,7 @@ func TestCreateChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
channel2.Name = "a" + model.NewId() + "a"
channel3.Name = "a" + model.NewId() + "a"
@@ -140,6 +144,7 @@ func TestCreateChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
channel2.Name = "a" + model.NewId() + "a"
channel3.Name = "a" + model.NewId() + "a"
@@ -286,10 +291,12 @@ func TestUpdateChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
utils.IsLicensed = isLicensed
utils.SetDefaultRolesBasedOnConfig()
}()
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
utils.IsLicensed = true
utils.SetDefaultRolesBasedOnConfig()
channel2 := th.CreateChannel(Client, team)
channel3 := th.CreatePrivateChannel(Client, team)
@@ -310,6 +317,7 @@ func TestUpdateChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannel(channel2); err == nil {
t.Fatal("should have errored not team admin")
@@ -332,6 +340,7 @@ func TestUpdateChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannel(channel2); err == nil {
t.Fatal("should have errored not system admin")
@@ -419,10 +428,12 @@ func TestUpdateChannelHeader(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
utils.IsLicensed = isLicensed
utils.SetDefaultRolesBasedOnConfig()
}()
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
utils.IsLicensed = true
utils.SetDefaultRolesBasedOnConfig()
th.LoginBasic()
channel2 := th.CreateChannel(Client, team)
@@ -447,6 +458,7 @@ func TestUpdateChannelHeader(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelHeader(data2); err == nil {
t.Fatal("should have errored not team admin")
@@ -469,6 +481,7 @@ func TestUpdateChannelHeader(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelHeader(data2); err == nil {
t.Fatal("should have errored not system admin")
@@ -545,10 +558,12 @@ func TestUpdateChannelPurpose(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
utils.IsLicensed = isLicensed
utils.SetDefaultRolesBasedOnConfig()
}()
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
utils.IsLicensed = true
utils.SetDefaultRolesBasedOnConfig()
th.LoginBasic()
channel2 := th.CreateChannel(Client, team)
@@ -573,6 +588,7 @@ func TestUpdateChannelPurpose(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelPurpose(data2); err == nil {
t.Fatal("should have errored not team admin")
@@ -595,6 +611,7 @@ func TestUpdateChannelPurpose(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelPurpose(data2); err == nil {
t.Fatal("should have errored not system admin")
@@ -986,10 +1003,12 @@ func TestDeleteChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel
utils.IsLicensed = isLicensed
utils.SetDefaultRolesBasedOnConfig()
}()
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL
utils.IsLicensed = true
utils.SetDefaultRolesBasedOnConfig()
th.LoginSystemAdmin()
LinkUserToTeam(th.BasicUser, team)
@@ -1013,6 +1032,7 @@ func TestDeleteChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
th.LoginSystemAdmin()
@@ -1044,6 +1064,7 @@ func TestDeleteChannel(t *testing.T) {
*utils.Cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
*utils.Cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
th.LoginSystemAdmin()

View File

@@ -118,7 +118,7 @@ func TestCliAssignRole(t *testing.T) {
th := Setup().InitBasic()
cmd := exec.Command("bash", "-c", `go run ../mattermost.go -assign_role -email="`+th.BasicUser.Email+`" -role="system_admin"`)
cmd := exec.Command("bash", "-c", `go run ../mattermost.go -assign_role -email="`+th.BasicUser.Email+`" -role="system_user system_admin"`)
output, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(output))
@@ -129,7 +129,7 @@ func TestCliAssignRole(t *testing.T) {
t.Fatal()
} else {
user := result.Data.(*model.User)
if user.Roles != "system_admin" {
if user.Roles != "system_user system_admin" {
t.Fatal()
}
}

View File

@@ -97,9 +97,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
}
if len(channelId) > 0 {
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
if !c.HasPermissionsToChannel(cchan, "checkCommand") {
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_USE_SLASH_COMMANDS) {
return
}
}
@@ -272,12 +270,10 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("createCommand", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_SLASH_COMMANDS) {
c.Err = model.NewLocAppError("createCommand", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -330,12 +326,10 @@ func listTeamCommands(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("listTeamCommands", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_SLASH_COMMANDS) {
c.Err = model.NewLocAppError("listTeamCommands", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if result := <-Srv.Store.Command().GetByTeam(c.TeamId); result.Err != nil {
@@ -354,12 +348,10 @@ func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("regenCommandToken", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_SLASH_COMMANDS) {
c.Err = model.NewLocAppError("regenCommandToken", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -379,7 +371,7 @@ func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) {
} else {
cmd = result.Data.(*model.Command)
if c.TeamId != cmd.TeamId || (c.Session.UserId != cmd.CreatorId && !c.IsTeamAdmin()) {
if c.TeamId != cmd.TeamId || (c.Session.UserId != cmd.CreatorId && !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS)) {
c.LogAudit("fail - inappropriate permissions")
c.Err = model.NewLocAppError("regenToken", "api.command.regen.app_error", nil, "user_id="+c.Session.UserId)
return
@@ -403,12 +395,10 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("deleteCommand", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_SLASH_COMMANDS) {
c.Err = model.NewLocAppError("deleteCommand", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -425,7 +415,7 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = result.Err
return
} else {
if c.TeamId != result.Data.(*model.Command).TeamId || (c.Session.UserId != result.Data.(*model.Command).CreatorId && !c.IsTeamAdmin()) {
if c.TeamId != result.Data.(*model.Command).TeamId || (c.Session.UserId != result.Data.(*model.Command).CreatorId && HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_OTHERS_SLASH_COMMANDS)) {
c.LogAudit("fail - inappropriate permissions")
c.Err = model.NewLocAppError("deleteCommand", "api.command.delete.app_error", nil, "user_id="+c.Session.UserId)
return

View File

@@ -16,7 +16,6 @@ import (
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
@@ -77,6 +76,10 @@ func ApiAdminSystemRequired(h func(*Context, http.ResponseWriter, *http.Request)
return &handler{h, true, true, true, false, false, false}
}
func ApiAdminSystemRequiredTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
return &handler{h, true, true, true, false, false, true}
}
func ApiAppHandlerTrustRequester(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
return &handler{h, false, false, true, false, false, true}
}
@@ -202,10 +205,6 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c.SystemAdminRequired()
}
if c.Err == nil && len(c.TeamId) > 0 && !h.isTeamIndependent {
c.HasPermissionsToTeam(c.TeamId, "TeamRoute")
}
if c.Err == nil && h.isUserActivity && token != "" && len(c.Session.UserId) > 0 {
SetStatusOnline(c.Session.UserId, c.Session.Id, false)
}
@@ -320,90 +319,13 @@ func (c *Context) SystemAdminRequired() {
c.Err = model.NewLocAppError("", "api.context.session_expired.app_error", nil, "SystemAdminRequired")
c.Err.StatusCode = http.StatusUnauthorized
return
} else if !c.IsSystemAdmin() {
} else if !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
c.Err = model.NewLocAppError("", "api.context.permissions.app_error", nil, "AdminRequired")
c.Err.StatusCode = http.StatusForbidden
return
}
}
func (c *Context) HasPermissionsToUser(userId string, where string) bool {
// You are the user
if c.Session.UserId == userId {
return true
}
// You're a mattermost system admin and you're on the VPN
if c.IsSystemAdmin() {
return true
}
c.Err = model.NewLocAppError(where, "api.context.permissions.app_error", nil, "userId="+userId)
c.Err.StatusCode = http.StatusForbidden
return false
}
func (c *Context) HasPermissionsToTeam(teamId string, where string) bool {
if c.IsSystemAdmin() {
return true
}
for _, teamMember := range c.Session.TeamMembers {
if teamId == teamMember.TeamId {
return true
}
}
c.Err = model.NewLocAppError(where, "api.context.permissions.app_error", nil, "userId="+c.Session.UserId+", teamId="+teamId)
c.Err.StatusCode = http.StatusForbidden
return false
}
func (c *Context) HasPermissionsToChannel(sc store.StoreChannel, where string) bool {
if cresult := <-sc; cresult.Err != nil {
c.Err = cresult.Err
return false
} else if cresult.Data.(int64) != 1 {
c.Err = model.NewLocAppError(where, "api.context.permissions.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
return false
}
return true
}
func (c *Context) HasSystemAdminPermissions(where string) bool {
if c.IsSystemAdmin() {
return true
}
c.Err = model.NewLocAppError(where, "api.context.system_permissions.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
return false
}
func (c *Context) IsSystemAdmin() bool {
if model.IsInRole(c.Session.Roles, model.ROLE_SYSTEM_ADMIN) {
return true
}
return false
}
func (c *Context) IsTeamAdmin() bool {
if c.IsSystemAdmin() {
return true
}
teamMember := c.Session.GetTeamByTeamId(c.TeamId)
if teamMember == nil {
return false
}
return teamMember.IsTeamAdmin()
}
func (c *Context) RemoveSessionCookie(w http.ResponseWriter, r *http.Request) {
cookie := &http.Cookie{
Name: model.SESSION_COOKIE_TOKEN,
@@ -463,6 +385,10 @@ func (c *Context) GetSiteURL() string {
return c.siteURL
}
func (c *Context) GetCurrentTeamMember() *model.TeamMember {
return c.Session.GetTeamByTeamId(c.TeamId)
}
func IsApiCall(r *http.Request) bool {
return strings.Index(r.URL.Path, "/api/") == 0
}

View File

@@ -8,26 +8,6 @@ import (
"testing"
)
func TestContext(t *testing.T) {
context := Context{}
context.IpAddress = "127.0.0.1"
context.Session.UserId = "5"
if !context.HasPermissionsToUser("5", "") {
t.Fatal("should have permissions")
}
if context.HasPermissionsToUser("6", "") {
t.Fatal("shouldn't have permissions")
}
context.Session.Roles = model.ROLE_SYSTEM_ADMIN
if !context.HasPermissionsToUser("6", "") {
t.Fatal("should have permissions")
}
}
func TestCache(t *testing.T) {
session := &model.Session{
Id: model.NewId(),

View File

@@ -182,7 +182,7 @@ func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = result.Err
return
} else {
if c.Session.UserId != result.Data.(*model.Emoji).CreatorId && !c.IsSystemAdmin() {
if c.Session.UserId != result.Data.(*model.Emoji).CreatorId && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
c.Err = model.NewLocAppError("deleteEmoji", "api.emoji.delete.permissions.app_error", nil, "user_id="+c.Session.UserId)
c.Err.StatusCode = http.StatusUnauthorized
return

View File

@@ -103,8 +103,6 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
files := m.File["files"]
resStruct := &model.FileUploadResponse{
@@ -115,7 +113,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
imageNameList := []string{}
imageDataList := [][]byte{}
if !c.HasPermissionsToChannel(cchan, "uploadFile") {
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_UPLOAD_FILE) {
return
}
@@ -318,7 +316,9 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_READ_CHANNEL) {
return
}
path := "teams/" + c.TeamId + "/channels/" + channelId + "/users/" + userId + "/" + filename
var info *model.FileInfo
@@ -339,10 +339,6 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
if !c.HasPermissionsToChannel(cchan, "getFileInfo") {
return
}
w.Header().Set("Cache-Control", "max-age=2592000, public")
w.Write([]byte(info.ToJson()))
@@ -356,7 +352,7 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
userId := params["user_id"]
filename := params["filename"]
if !c.HasPermissionsToChannel(Srv.Store.Channel().CheckPermissionsTo(teamId, channelId, c.Session.UserId), "getFile") {
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_READ_CHANNEL) {
return
}
@@ -512,14 +508,12 @@ func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
userId := matches[0][2]
filename = matches[0][3]
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
url := generatePublicLink(c.GetSiteURL(), c.TeamId, channelId, userId, filename)
if !c.HasPermissionsToChannel(cchan, "getPublicLink") {
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_GET_PUBLIC_LINK) {
return
}
url := generatePublicLink(c.GetSiteURL(), c.TeamId, channelId, userId, filename)
w.Write([]byte(model.StringToJson(url)))
}

View File

@@ -173,14 +173,17 @@ func RemoveLicense() *model.AppError {
}
func getClientLicenceConfig(c *Context, w http.ResponseWriter, r *http.Request) {
etag := utils.GetClientLicenseEtag(!c.IsSystemAdmin())
useSanitizedLicense := !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM)
c.Err = nil
etag := utils.GetClientLicenseEtag(useSanitizedLicense)
if HandleEtag(etag, w, r) {
return
}
var clientLicense map[string]string
if c.IsSystemAdmin() {
if useSanitizedLicense {
clientLicense = utils.ClientLicense
} else {
clientLicense = utils.GetSanitizedClientLicense()

View File

@@ -53,12 +53,10 @@ func registerOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !c.IsSystemAdmin() {
c.Err = model.NewLocAppError("registerOAuthApp", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToContext(c, model.PERMISSION_MANAGE_OAUTH) {
c.Err = model.NewLocAppError("registerOAuthApp", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
app := model.OAuthAppFromJson(r.Body)
@@ -94,18 +92,14 @@ func getOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
isSystemAdmin := c.IsSystemAdmin()
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !isSystemAdmin {
c.Err = model.NewLocAppError("getOAuthAppsByUser", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToContext(c, model.PERMISSION_MANAGE_OAUTH) {
c.Err = model.NewLocAppError("getOAuthApps", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
var ochan store.StoreChannel
if isSystemAdmin {
if HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
ochan = Srv.Store.OAuth().GetApps()
} else {
ochan = Srv.Store.OAuth().GetAppByUser(c.Session.UserId)
@@ -872,14 +866,10 @@ func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
isSystemAdmin := c.IsSystemAdmin()
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !isSystemAdmin {
c.Err = model.NewLocAppError("deleteOAuthApp", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToContext(c, model.PERMISSION_MANAGE_OAUTH) {
c.Err = model.NewLocAppError("deleteOAuthApp", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -896,7 +886,7 @@ func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = result.Err
return
} else {
if c.Session.UserId != result.Data.(*model.OAuthApp).CreatorId && !isSystemAdmin {
if c.Session.UserId != result.Data.(*model.OAuthApp).CreatorId && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
c.LogAudit("fail - inappropriate permissions")
c.Err = model.NewLocAppError("deleteOAuthApp", "api.oauth.delete.permissions.app_error", nil, "user_id="+c.Session.UserId)
return
@@ -964,16 +954,6 @@ func regenerateOAuthSecret(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
isSystemAdmin := c.IsSystemAdmin()
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !isSystemAdmin {
c.Err = model.NewLocAppError("registerOAuthApp", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
}
params := mux.Vars(r)
id := params["id"]
@@ -989,9 +969,9 @@ func regenerateOAuthSecret(c *Context, w http.ResponseWriter, r *http.Request) {
} else {
app = result.Data.(*model.OAuthApp)
//validate that is a System Admin or the same user that registered the app
if !isSystemAdmin && app.CreatorId != c.Session.UserId {
c.Err = model.NewLocAppError("regenerateOAuthSecret", "api.oauth.regenerate_secret.app_error", nil, "")
if app.CreatorId != c.Session.UserId && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
c.Err = model.NewLocAppError("registerOAuthApp", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}

View File

@@ -161,6 +161,7 @@ func TestGetOAuthAppsByUser(t *testing.T) {
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
if result, err := Client.GetOAuthAppsByUser(); err != nil {
t.Fatal(err)
@@ -316,6 +317,7 @@ func TestOAuthDeleteApp(t *testing.T) {
utils.Cfg.ServiceSettings.EnableOAuthServiceProvider = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
app := &model.OAuthApp{Name: "TestApp5" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}

View File

@@ -59,10 +59,24 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) {
}
post.UserId = c.Session.UserId
// Create and save post object to channel
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
cchan := Srv.Store.Channel().Get(post.ChannelId)
if !c.HasPermissionsToChannel(cchan, "createPost") {
if !HasPermissionToChannelContext(c, post.ChannelId, model.PERMISSION_CREATE_POST) {
return
}
// Check that channel has not been deleted
var channel *model.Channel
if result := <-cchan; result.Err != nil {
c.SetInvalidParam("createPost", "post.channelId")
return
} else {
channel = result.Data.(*model.Channel)
}
if channel.DeleteAt != 0 {
c.Err = model.NewLocAppError("createPost", "api.post.create_post.can_not_post_to_deleted.error", nil, "")
c.Err.StatusCode = http.StatusBadRequest
return
}
@@ -1099,10 +1113,9 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
pchan := Srv.Store.Post().Get(post.Id)
if !c.HasPermissionsToChannel(cchan, "updatePost") {
if !HasPermissionToChannelContext(c, post.ChannelId, model.PERMISSION_EDIT_POST) {
return
}
@@ -1204,10 +1217,9 @@ func getPosts(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
etagChan := Srv.Store.Post().GetEtag(id)
if !c.HasPermissionsToChannel(cchan, "getPosts") {
if !HasPermissionToChannelContext(c, id, model.PERMISSION_CREATE_POST) {
return
}
@@ -1246,10 +1258,9 @@ func getPostsSince(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
pchan := Srv.Store.Post().GetPostsSince(id, time)
if !c.HasPermissionsToChannel(cchan, "getPostsSince") {
if !HasPermissionToChannelContext(c, id, model.PERMISSION_READ_CHANNEL) {
return
}
@@ -1279,10 +1290,9 @@ func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
pchan := Srv.Store.Post().Get(postId)
if !c.HasPermissionsToChannel(cchan, "getPost") {
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_READ_CHANNEL) {
return
}
@@ -1326,8 +1336,7 @@ func getPostById(c *Context, w http.ResponseWriter, r *http.Request) {
}
post := list.Posts[list.Order[0]]
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
if !c.HasPermissionsToChannel(cchan, "getPostById") {
if !HasPermissionToChannelContext(c, post.ChannelId, model.PERMISSION_READ_CHANNEL) {
return
}
@@ -1361,12 +1370,7 @@ func getPermalinkTmp(c *Context, w http.ResponseWriter, r *http.Request) {
}
post := list.Posts[list.Order[0]]
if !c.HasPermissionsToTeam(c.TeamId, "permalink") {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, post.ChannelId, c.Session.UserId)
if !c.HasPermissionsToChannel(cchan, "getPermalinkTmp") {
if !HasPermissionToChannelContext(c, post.ChannelId, model.PERMISSION_READ_CHANNEL) {
// If we don't have permissions attempt to join the channel to fix the problem
if err, _ := JoinChannelById(c, c.Session.UserId, post.ChannelId); err != nil {
// On error just return with permissions error
@@ -1402,7 +1406,10 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, channelId, c.Session.UserId)
if !HasPermissionToChannelContext(c, channelId, model.PERMISSION_EDIT_POST) {
return
}
pchan := Srv.Store.Post().Get(postId)
if result := <-pchan; result.Err != nil {
@@ -1412,10 +1419,6 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
post := result.Data.(*model.PostList).Posts[postId]
if !c.HasPermissionsToChannel(cchan, "deletePost") && !c.IsTeamAdmin() {
return
}
if post == nil {
c.SetInvalidParam("deletePost", "postId")
return
@@ -1427,7 +1430,7 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if post.UserId != c.Session.UserId && !c.IsTeamAdmin() {
if post.UserId != c.Session.UserId && !HasPermissionToChannelContext(c, post.ChannelId, model.PERMISSION_EDIT_OTHERS_POSTS) {
c.Err = model.NewLocAppError("deletePost", "api.post.delete_post.permissions.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
@@ -1507,11 +1510,10 @@ func getPostsBeforeOrAfter(c *Context, w http.ResponseWriter, r *http.Request, b
return
}
cchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, id, c.Session.UserId)
// We can do better than this etag in this situation
etagChan := Srv.Store.Post().GetEtag(id)
if !c.HasPermissionsToChannel(cchan, "getPostsBeforeOrAfter") {
if !HasPermissionToChannelContext(c, id, model.PERMISSION_READ_CHANNEL) {
return
}

View File

@@ -778,6 +778,7 @@ func TestDeletePosts(t *testing.T) {
post4 = Client.Must(Client.CreatePost(post4)).Data.(*model.Post)
th.LoginBasic2()
Client.Must(Client.JoinChannel(channel1.Id))
Client.Must(Client.DeletePost(channel1.Id, post4.Id))
}

View File

@@ -259,9 +259,18 @@ func JoinUserToTeamById(teamId string, user *model.User) *model.AppError {
func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError {
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id}
tm := &model.TeamMember{
TeamId: team.Id,
UserId: user.Id,
Roles: model.ROLE_TEAM_USER.Id,
}
channelRole := ""
channelRole := model.ROLE_CHANNEL_USER.Id
if team.Email == user.Email {
tm.Roles = model.ROLE_TEAM_USER.Id + " " + model.ROLE_TEAM_ADMIN.Id
channelRole = model.ROLE_CHANNEL_USER.Id + " " + model.ROLE_CHANNEL_ADMIN.Id
}
if etmr := <-Srv.Store.Team().GetMember(team.Id, user.Id); etmr.Err == nil {
// Membership alredy exists. Check if deleted and and update, otherwise do nothing
@@ -276,11 +285,6 @@ func JoinUserToTeam(team *model.Team, user *model.User) *model.AppError {
return tmr.Err
}
} else {
if team.Email == user.Email {
tm.Roles = model.ROLE_TEAM_ADMIN
channelRole = model.CHANNEL_ROLE_ADMIN
}
// Membership appears to be missing. Lets try to add.
if tmr := <-Srv.Store.Team().SaveMember(tm); tmr.Err != nil {
return tmr.Err
@@ -361,7 +365,7 @@ func isTeamCreationAllowed(c *Context, email string) bool {
email = strings.ToLower(email)
if !c.IsSystemAdmin() && !utils.Cfg.TeamSettings.EnableTeamCreation {
if !utils.Cfg.TeamSettings.EnableTeamCreation && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
c.Err = model.NewLocAppError("isTeamCreationAllowed", "api.team.is_team_creation_allowed.disabled.app_error", nil, "")
return false
}
@@ -402,9 +406,10 @@ func GetAllTeamListings(c *Context, w http.ResponseWriter, r *http.Request) {
m := make(map[string]*model.Team)
for _, v := range teams {
m[v.Id] = v
if !c.IsSystemAdmin() {
if !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
m[v.Id].Sanitize()
}
c.Err = nil
}
w.Write([]byte(model.TeamMapToJson(m)))
@@ -415,9 +420,10 @@ func GetAllTeamListings(c *Context, w http.ResponseWriter, r *http.Request) {
// on the server. Otherwise, it will only be the teams of which the user is a member.
func getAll(c *Context, w http.ResponseWriter, r *http.Request) {
var tchan store.StoreChannel
if c.IsSystemAdmin() {
if HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
tchan = Srv.Store.Team().GetAll()
} else {
c.Err = nil
tchan = Srv.Store.Team().GetTeamsByUserId(c.Session.UserId)
}
@@ -472,13 +478,14 @@ func inviteMembers(c *Context, w http.ResponseWriter, r *http.Request) {
}
if utils.IsLicensed {
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, "")
return
}
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, "")
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_INVITE_USER) {
if *utils.Cfg.TeamSettings.RestrictTeamInvite == model.PERMISSIONS_SYSTEM_ADMIN {
c.Err = model.NewLocAppError("inviteMembers", "api.team.invite_members.restricted_system_admin.app_error", nil, "")
}
if *utils.Cfg.TeamSettings.RestrictTeamInvite == model.PERMISSIONS_TEAM_ADMIN {
c.Err = model.NewLocAppError("inviteMembers", "api.team.invite_members.restricted_team_admin.app_error", nil, "")
}
c.Err.StatusCode = http.StatusForbidden
return
}
}
@@ -540,9 +547,7 @@ func addUserToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
user = result.Data.(*model.User)
}
if !c.IsTeamAdmin() {
c.Err = model.NewLocAppError("addUserToTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
if !HasPermissionToTeamContext(c, team.Id, model.PERMISSION_ADD_USER_TO_TEAM) {
return
}
@@ -584,9 +589,7 @@ func removeUserFromTeam(c *Context, w http.ResponseWriter, r *http.Request) {
}
if c.Session.UserId != user.Id {
if !c.IsTeamAdmin() {
c.Err = model.NewLocAppError("removeUserFromTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
if !HasPermissionToTeamContext(c, team.Id, model.PERMISSION_REMOVE_USER_FROM_TEAM) {
return
}
}
@@ -703,12 +706,7 @@ func InviteMembers(c *Context, team *model.Team, user *model.User, invites []str
sender := user.GetDisplayName()
senderRole := ""
if c.IsTeamAdmin() {
senderRole = c.T("api.team.invite_members.admin")
} else {
senderRole = c.T("api.team.invite_members.member")
}
senderRole := c.T("api.team.invite_members.member")
subjectPage := utils.NewHTMLTemplate("invite_subject", c.Locale)
subjectPage.Props["Subject"] = c.T("api.templates.invite_subject",
@@ -755,7 +753,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
team.Id = c.TeamId
if !c.IsTeamAdmin() {
if !HasPermissionToTeamContext(c, team.Id, model.PERMISSION_MANAGE_TEAM) {
c.Err = model.NewLocAppError("updateTeam", "api.team.update_team.permissions.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
return
@@ -833,7 +831,7 @@ func getMyTeam(c *Context, w http.ResponseWriter, r *http.Request) {
}
func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.HasPermissionsToTeam(c.TeamId, "import") || !c.IsTeamAdmin() {
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_IMPORT_TEAM) {
c.Err = model.NewLocAppError("importTeam", "api.team.import_team.admin.app_error", nil, "userId="+c.Session.UserId)
c.Err.StatusCode = http.StatusForbidden
return
@@ -930,7 +928,7 @@ func getMembers(c *Context, w http.ResponseWriter, r *http.Request) {
id := params["id"]
if c.Session.GetTeamByTeamId(id) == nil {
if !c.HasSystemAdminPermissions("getMembers") {
if !HasPermissionToTeamContext(c, id, model.PERMISSION_MANAGE_SYSTEM) {
return
}
}

View File

@@ -175,14 +175,14 @@ func TestRemoveUserFromTeam(t *testing.T) {
t.Fatal("should fail not enough permissions")
} else {
if err.Id != "api.context.permissions.app_error" {
t.Fatal("wrong error")
t.Fatal("wrong error. Got: " + err.Id)
}
}
if _, err := th.BasicClient.RemoveUserFromTeam("", th.SystemAdminUser.Id); err == nil {
t.Fatal("should fail not enough permissions")
} else {
if err.Id != "api.team.update_team.permissions.app_error" {
if err.Id != "api.context.permissions.app_error" {
t.Fatal("wrong error")
}
}
@@ -318,7 +318,7 @@ func TestGetAllTeamListings(t *testing.T) {
c := &Context{}
c.RequestId = model.NewId()
c.IpAddress = "cmd_line"
UpdateUserRoles(c, user, model.ROLE_SYSTEM_ADMIN)
UpdateUserRoles(c, user, model.ROLE_SYSTEM_ADMIN.Id)
Client.Login(user.Email, "passwd1")
Client.SetTeamId(team.Id)
@@ -415,8 +415,10 @@ func TestInviteMembers(t *testing.T) {
restrictTeamInvite := *utils.Cfg.TeamSettings.RestrictTeamInvite
defer func() {
*utils.Cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite
utils.SetDefaultRolesBasedOnConfig()
}()
*utils.Cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
th.LoginBasic2()
LinkUserToTeam(th.BasicUser2, team)
@@ -445,6 +447,7 @@ func TestInviteMembers(t *testing.T) {
}
*utils.Cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.InviteMembers(invites); err == nil {
t.Fatal("should have errored not system admin and licensed")

View File

@@ -230,16 +230,16 @@ func IsVerifyHashRequired(user *model.User, team *model.Team, hash string) bool
func CreateUser(user *model.User) (*model.User, *model.AppError) {
user.Roles = ""
user.Roles = model.ROLE_SYSTEM_USER.Id
// Below is a special case where the first user in the entire
// system is granted the system_admin role instead of admin
// system is granted the system_admin role
if result := <-Srv.Store.User().GetTotalUsersCount(); result.Err != nil {
return nil, result.Err
} else {
count := result.Data.(int64)
if count <= 0 {
user.Roles = model.ROLE_SYSTEM_ADMIN
user.Roles = model.ROLE_SYSTEM_ADMIN.Id + " " + model.ROLE_SYSTEM_USER.Id
}
}
@@ -561,7 +561,7 @@ func LoginByOAuth(c *Context, w http.ResponseWriter, r *http.Request, service st
// User MUST be authenticated completely before calling Login
func doLogin(c *Context, w http.ResponseWriter, r *http.Request, user *model.User, deviceId string) {
session := &model.Session{UserId: user.Id, Roles: user.Roles, DeviceId: deviceId, IsOAuth: false}
session := &model.Session{UserId: user.Id, Roles: user.GetRawRoles(), DeviceId: deviceId, IsOAuth: false}
maxAge := *utils.Cfg.ServiceSettings.SessionLengthWebInDays * 60 * 60 * 24
@@ -788,7 +788,7 @@ func getSessions(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["user_id"]
if !c.HasPermissionsToUser(id, "getSessions") {
if !HasPermissionToUser(c, id) {
return
}
@@ -918,11 +918,12 @@ func getInitialLoad(c *Context, w http.ResponseWriter, r *http.Request) {
}
il.ClientCfg = utils.ClientCfg
if c.IsSystemAdmin() {
if HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
il.LicenseCfg = utils.ClientLicense
} else {
il.LicenseCfg = utils.GetSanitizedClientLicense()
}
c.Err = nil
w.Write([]byte(il.ToJson()))
}
@@ -931,7 +932,7 @@ func getUser(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["user_id"]
if !c.HasPermissionsToUser(id, "getUser") {
if !HasPermissionToUser(c, id) {
return
}
@@ -956,7 +957,7 @@ func getProfilesForDirectMessageList(c *Context, w http.ResponseWriter, r *http.
if *utils.Cfg.TeamSettings.RestrictDirectMessage == model.DIRECT_MESSAGE_TEAM {
if c.Session.GetTeamByTeamId(id) == nil {
if !c.HasSystemAdminPermissions("getProfiles") {
if !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
return
}
}
@@ -985,7 +986,7 @@ func getProfiles(c *Context, w http.ResponseWriter, r *http.Request) {
id := params["id"]
if c.Session.GetTeamByTeamId(id) == nil {
if !c.HasSystemAdminPermissions("getProfiles") {
if !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
return
}
}
@@ -1035,7 +1036,7 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["user_id"]
if !c.HasPermissionsToUser(id, "getAudits") {
if !HasPermissionToUser(c, id) {
return
}
@@ -1292,7 +1293,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.HasPermissionsToUser(user.Id, "updateUser") {
if !HasPermissionToUser(c, user.Id) {
return
}
@@ -1432,22 +1433,21 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
}
new_roles := props["new_roles"]
if !(model.IsValidUserRoles(new_roles) || model.IsValidTeamRoles(new_roles)) {
if !(model.IsValidUserRoles(new_roles)) {
c.SetInvalidParam("updateRoles", "new_roles")
return
}
// If you are not the team admin then you can only demote yourself
if !c.IsTeamAdmin() && user_id != c.Session.UserId {
if user_id != c.Session.UserId && !HasPermissionToTeamContext(c, team_id, model.PERMISSION_MANAGE_ROLES) {
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.team_admin_needed.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
// Only another system admin can add the system admin role
if model.IsInRole(new_roles, model.ROLE_SYSTEM_ADMIN) && !c.IsSystemAdmin() {
// If your trying to assign the system admin role, you must have that permission
if model.IsInRole(new_roles, model.ROLE_SYSTEM_ADMIN.Id) && !HasPermissionToContext(c, model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE) {
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.system_admin_set.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
@@ -1459,15 +1459,15 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
user = result.Data.(*model.User)
}
// only another system admin can remove another system admin
if model.IsInRole(user.Roles, model.ROLE_SYSTEM_ADMIN) && !c.IsSystemAdmin() {
// only another system admin can modify another system admin
if model.IsInRole(user.GetRawRoles(), model.ROLE_SYSTEM_ADMIN.Id) && !HasPermissionToContext(c, model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE) {
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.system_admin_needed.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
// if the team role has changed then lets update team members
if model.IsValidTeamRoles(new_roles) && len(team_id) > 0 {
if len(team_id) > 0 {
var members []*model.TeamMember
if result := <-Srv.Store.Team().GetTeamsForUser(user_id); result.Err != nil {
@@ -1489,7 +1489,7 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.IsSystemAdmin() {
if !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
currentUserTeamMember := c.Session.GetTeamByTeamId(team_id)
// Only the system admin can modify other team
@@ -1500,12 +1500,13 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
}
// Only another team admin can make a team admin
if !currentUserTeamMember.IsTeamAdmin() && model.IsInRole(new_roles, model.ROLE_TEAM_ADMIN) {
if model.IsInRole(new_roles, model.ROLE_TEAM_ADMIN.Id) && !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_ROLES) {
c.Err = model.NewLocAppError("updateRoles", "api.user.update_roles.team_admin_needed.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
}
c.Err = nil
member.Roles = new_roles
@@ -1513,10 +1514,8 @@ func updateRoles(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = result.Err
return
}
}
// If the users role has changed then lets update the user
if model.IsValidUserRoles(new_roles) {
} else {
// If the users role has changed then lets update the user
UpdateUserRoles(c, user, new_roles)
if c.Err != nil {
return
@@ -1575,7 +1574,7 @@ func updateActive(c *Context, w http.ResponseWriter, r *http.Request) {
// true when you're trying to de-activate yourself
isSelfDeactive := !active && user_id == c.Session.UserId
if !isSelfDeactive && !c.IsSystemAdmin() {
if !isSelfDeactive && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
c.Err = model.NewLocAppError("updateActive", "api.user.update_active.permissions.app_error", nil, "userId="+user_id)
c.Err.StatusCode = http.StatusForbidden
return
@@ -1626,7 +1625,7 @@ func PermanentDeleteUser(c *Context, user *model.User) *model.AppError {
c.Path = "/users/permanent_delete"
c.LogAuditWithUserId(user.Id, fmt.Sprintf("attempt userId=%v", user.Id))
c.LogAuditWithUserId("", fmt.Sprintf("attempt userId=%v", user.Id))
if user.IsInRole(model.ROLE_SYSTEM_ADMIN) {
if user.IsInRole(model.ROLE_SYSTEM_ADMIN.Id) {
l4g.Warn(utils.T("api.user.permanent_delete_user.system_admin.warn"), user.Email)
}
@@ -1814,7 +1813,7 @@ func ResetPassword(c *Context, userId, newPassword string) *model.AppError {
user = result.Data.(*model.User)
}
if user.AuthData != nil && len(*user.AuthData) != 0 && !c.IsSystemAdmin() {
if user.AuthData != nil && len(*user.AuthData) != 0 && !HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
return model.NewLocAppError("ResetPassword", "api.user.reset_password.sso.app_error", nil, "userId="+user.Id)
}
@@ -1911,7 +1910,7 @@ func updateUserNotify(c *Context, w http.ResponseWriter, r *http.Request) {
uchan := Srv.Store.User().Get(user_id)
if !c.HasPermissionsToUser(user_id, "updateUserNotify") {
if !HasPermissionToUser(c, user_id) {
return
}
@@ -2567,10 +2566,11 @@ func userTyping(req *model.WebSocketRequest) (map[string]interface{}, *model.App
func sanitizeProfile(c *Context, user *model.User) *model.User {
options := utils.Cfg.GetSanitizeOptions()
if c.IsSystemAdmin() {
if HasPermissionToContext(c, model.PERMISSION_MANAGE_SYSTEM) {
options["email"] = true
options["fullname"] = true
}
c.Err = nil
user.SanitizeProfile(options)

View File

@@ -420,7 +420,7 @@ func TestGetUser(t *testing.T) {
c := &Context{}
c.RequestId = model.NewId()
c.IpAddress = "cmd_line"
UpdateUserRoles(c, ruser.Data.(*model.User), model.ROLE_SYSTEM_ADMIN)
UpdateUserRoles(c, ruser.Data.(*model.User), model.ROLE_SYSTEM_ADMIN.Id)
Client.Login(user.Email, "passwd1")
@@ -748,7 +748,7 @@ func TestUserUpdate(t *testing.T) {
Client.SetTeamId(team.Id)
user.Nickname = "Jim Jimmy"
user.Roles = model.ROLE_TEAM_ADMIN
user.Roles = model.ROLE_SYSTEM_ADMIN.Id
user.LastPasswordUpdate = 123
if result, err := Client.UpdateUser(user); err != nil {
@@ -757,7 +757,7 @@ func TestUserUpdate(t *testing.T) {
if result.Data.(*model.User).Nickname != "Jim Jimmy" {
t.Fatal("Nickname did not update properly")
}
if result.Data.(*model.User).Roles != "" {
if result.Data.(*model.User).Roles != model.ROLE_SYSTEM_USER.Id {
t.Fatal("Roles should not have updated")
}
if result.Data.(*model.User).LastPasswordUpdate == 123 {
@@ -957,7 +957,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// user 1 is trying to promote user 2
data["user_id"] = th.BasicUser2.Id
data["new_roles"] = model.ROLE_TEAM_ADMIN
data["new_roles"] = model.ROLE_TEAM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
t.Fatal("Should have errored, you can only demote yourself")
@@ -965,7 +965,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// user 1 is trying to promote user 2
data["user_id"] = th.BasicUser2.Id
data["new_roles"] = model.ROLE_SYSTEM_ADMIN
data["new_roles"] = model.ROLE_SYSTEM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
t.Fatal("Should have errored, you can only demote yourself")
@@ -973,7 +973,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// user 1 is trying to promote himself
data["user_id"] = th.BasicUser.Id
data["new_roles"] = model.ROLE_TEAM_ADMIN
data["new_roles"] = model.ROLE_TEAM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
t.Fatal("Should have errored, you cannot elevate your permissions")
@@ -981,7 +981,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// user 1 is trying to promote himself
data["user_id"] = th.BasicUser.Id
data["new_roles"] = model.ROLE_SYSTEM_ADMIN
data["new_roles"] = model.ROLE_SYSTEM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
t.Fatal("Should have errored, you cannot elevate your permissions")
@@ -991,7 +991,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// promote user to team admin
data["user_id"] = th.BasicUser.Id
data["new_roles"] = model.ROLE_TEAM_ADMIN
data["new_roles"] = model.ROLE_TEAM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.SystemAdminClient.UpdateUserRoles(data); err != nil {
t.Fatal("Should have succeeded since they are system admin")
@@ -1007,7 +1007,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// re-promote user to team admin
data["user_id"] = th.BasicUser.Id
data["new_roles"] = model.ROLE_TEAM_ADMIN
data["new_roles"] = model.ROLE_TEAM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.SystemAdminClient.UpdateUserRoles(data); err != nil {
t.Fatal("Should have succeeded since they are system admin")
@@ -1015,7 +1015,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// user 1 is promoting user 2 to team admin
data["user_id"] = th.BasicUser2.Id
data["new_roles"] = model.ROLE_TEAM_ADMIN
data["new_roles"] = model.ROLE_TEAM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.BasicClient.UpdateUserRoles(data); err != nil {
t.Fatal("Should have succeeded since they are team admin")
@@ -1023,7 +1023,7 @@ func TestUserUpdateRolesMoreCases(t *testing.T) {
// user 1 is trying to promote user 2 from team admin to system admin
data["user_id"] = th.BasicUser2.Id
data["new_roles"] = model.ROLE_SYSTEM_ADMIN
data["new_roles"] = model.ROLE_SYSTEM_ADMIN.Id
data["team_id"] = th.BasicTeam.Id
if _, err := th.BasicClient.UpdateUserRoles(data); err == nil {
t.Fatal("Should have errored, can only be system admin")

View File

@@ -41,12 +41,8 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("createIncomingHook", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_WEBHOOKS) {
return
}
c.LogAudit("attempt")
@@ -59,7 +55,6 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
}
cchan := Srv.Store.Channel().Get(hook.ChannelId)
pchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, hook.ChannelId, c.Session.UserId)
hook.UserId = c.Session.UserId
hook.TeamId = c.TeamId
@@ -72,12 +67,9 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
channel = result.Data.(*model.Channel)
}
if !c.HasPermissionsToChannel(pchan, "createIncomingHook") {
if channel.Type != model.CHANNEL_OPEN || channel.TeamId != c.TeamId {
c.LogAudit("fail - bad channel permissions")
return
}
c.Err = nil
if channel.Type != model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_READ_CHANNEL) {
c.LogAudit("fail - bad channel permissions")
return
}
if result := <-Srv.Store.Webhook().SaveIncoming(hook); result.Err != nil {
@@ -97,12 +89,10 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("deleteIncomingHook", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_WEBHOOKS) {
c.Err = model.NewLocAppError("deleteIncomingHook", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -119,7 +109,7 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = result.Err
return
} else {
if c.Session.UserId != result.Data.(*model.IncomingWebhook).UserId && !c.IsTeamAdmin() {
if c.Session.UserId != result.Data.(*model.IncomingWebhook).UserId && !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
c.LogAudit("fail - inappropriate permissions")
c.Err = model.NewLocAppError("deleteIncomingHook", "api.webhook.delete_incoming.permissions.app_errror", nil, "user_id="+c.Session.UserId)
return
@@ -142,12 +132,10 @@ func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("getIncomingHooks", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_WEBHOOKS) {
c.Err = model.NewLocAppError("getIncomingHooks", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if result := <-Srv.Store.Webhook().GetIncomingByTeam(c.TeamId); result.Err != nil {
@@ -166,12 +154,10 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("createOutgoingHook", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_WEBHOOKS) {
c.Err = model.NewLocAppError("createOutgoingHook", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -188,7 +174,6 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
if len(hook.ChannelId) != 0 {
cchan := Srv.Store.Channel().Get(hook.ChannelId)
pchan := Srv.Store.Channel().CheckPermissionsTo(c.TeamId, hook.ChannelId, c.Session.UserId)
var channel *model.Channel
if result := <-cchan; result.Err != nil {
@@ -204,14 +189,10 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.HasPermissionsToChannel(pchan, "createOutgoingHook") {
if channel.Type != model.CHANNEL_OPEN || channel.TeamId != c.TeamId {
c.LogAudit("fail - bad channel permissions")
c.Err = model.NewLocAppError("createOutgoingHook", "api.webhook.create_outgoing.permissions.app_error", nil, "")
return
} else {
c.Err = nil
}
if channel.Type != model.CHANNEL_OPEN || channel.TeamId != c.TeamId {
c.LogAudit("fail - bad channel permissions")
c.Err = model.NewLocAppError("createOutgoingHook", "api.webhook.create_outgoing.permissions.app_error", nil, "")
return
}
} else if len(hook.TriggerWords) == 0 {
c.Err = model.NewLocAppError("createOutgoingHook", "api.webhook.create_outgoing.triggers.app_error", nil, "")
@@ -252,12 +233,10 @@ func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("getOutgoingHooks", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_WEBHOOKS) {
c.Err = model.NewLocAppError("getOutgoingHooks", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if result := <-Srv.Store.Webhook().GetOutgoingByTeam(c.TeamId); result.Err != nil {
@@ -276,12 +255,10 @@ func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("deleteOutgoingHook", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_WEBHOOKS) {
c.Err = model.NewLocAppError("deleteOutgoingHook", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -298,7 +275,7 @@ func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
c.Err = result.Err
return
} else {
if c.Session.UserId != result.Data.(*model.OutgoingWebhook).CreatorId && !c.IsTeamAdmin() {
if c.Session.UserId != result.Data.(*model.OutgoingWebhook).CreatorId && !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
c.LogAudit("fail - inappropriate permissions")
c.Err = model.NewLocAppError("deleteOutgoingHook", "api.webhook.delete_outgoing.permissions.app_error", nil, "user_id="+c.Session.UserId)
return
@@ -321,12 +298,10 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request)
return
}
if *utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations {
if !(c.IsSystemAdmin() || c.IsTeamAdmin()) {
c.Err = model.NewLocAppError("regenOutgoingHookToken", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
if !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_WEBHOOKS) {
c.Err = model.NewLocAppError("regenOutgoingHookToken", "api.command.admin_only.app_error", nil, "")
c.Err.StatusCode = http.StatusForbidden
return
}
c.LogAudit("attempt")
@@ -346,7 +321,7 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request)
} else {
hook = result.Data.(*model.OutgoingWebhook)
if c.TeamId != hook.TeamId && c.Session.UserId != hook.CreatorId && !c.IsTeamAdmin() {
if c.TeamId != hook.TeamId && c.Session.UserId != hook.CreatorId && !HasPermissionToCurrentTeamContext(c, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
c.LogAudit("fail - inappropriate permissions")
c.Err = model.NewLocAppError("regenOutgoingHookToken", "api.webhook.regen_outgoing_token.permissions.app_error", nil, "user_id="+c.Session.UserId)
return
@@ -465,18 +440,20 @@ func incomingWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
channel = result.Data.(*model.Channel)
}
pchan := Srv.Store.Channel().CheckPermissionsTo(hook.TeamId, channel.Id, hook.UserId)
// create a mock session
c.Session = model.Session{
UserId: hook.UserId,
TeamMembers: []*model.TeamMember{{TeamId: hook.TeamId, UserId: hook.UserId}},
IsOAuth: false,
UserId: hook.UserId,
TeamMembers: []*model.TeamMember{{
TeamId: hook.TeamId,
UserId: hook.UserId,
Roles: model.ROLE_CHANNEL_USER.Id,
}},
IsOAuth: false,
}
c.TeamId = hook.TeamId
if !c.HasPermissionsToChannel(pchan, "createIncomingHook") && channel.Type != model.CHANNEL_OPEN {
if channel.Type != model.CHANNEL_OPEN && !HasPermissionToChannelContext(c, channel.Id, model.PERMISSION_READ_CHANNEL) {
c.Err = model.NewLocAppError("incomingWebhook", "web.incoming_webhook.permissions.app_error", nil, "")
return
}

View File

@@ -26,9 +26,11 @@ func TestCreateIncomingHook(t *testing.T) {
defer func() {
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
@@ -85,7 +87,17 @@ func TestCreateIncomingHook(t *testing.T) {
t.Fatal("should have failed - not system/team admin")
}
Client.Logout()
UpdateUserToTeamAdmin(user2, team)
Client.Must(Client.LoginById(user2.Id, user2.Password))
Client.SetTeamId(team.Id)
if _, err := Client.CreateIncomingWebhook(hook); err != nil {
t.Fatal(err)
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.CreateIncomingWebhook(hook); err != nil {
t.Fatal(err)
@@ -117,9 +129,11 @@ func TestListIncomingHooks(t *testing.T) {
defer func() {
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook1 := &model.IncomingWebhook{ChannelId: channel1.Id}
hook1 = Client.Must(Client.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook)
@@ -146,6 +160,7 @@ func TestListIncomingHooks(t *testing.T) {
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.ListIncomingWebhooks(); err != nil {
t.Fatal(err)
@@ -171,9 +186,11 @@ func TestDeleteIncomingHook(t *testing.T) {
defer func() {
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableIncomingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook := &model.IncomingWebhook{ChannelId: channel1.Id}
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
@@ -207,6 +224,7 @@ func TestDeleteIncomingHook(t *testing.T) {
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
t.Fatal("should have failed - not creator or team admin")
@@ -244,9 +262,11 @@ func TestCreateOutgoingHook(t *testing.T) {
defer func() {
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
@@ -317,6 +337,7 @@ func TestCreateOutgoingHook(t *testing.T) {
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.CreateOutgoingWebhook(hook); err != nil {
t.Fatal(err)
@@ -350,9 +371,11 @@ func TestListOutgoingHooks(t *testing.T) {
defer func() {
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook1 = Client.Must(Client.CreateOutgoingWebhook(hook1)).Data.(*model.OutgoingWebhook)
@@ -379,6 +402,7 @@ func TestListOutgoingHooks(t *testing.T) {
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.ListOutgoingWebhooks(); err != nil {
t.Fatal(err)
@@ -404,9 +428,11 @@ func TestDeleteOutgoingHook(t *testing.T) {
defer func() {
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
@@ -440,6 +466,7 @@ func TestDeleteOutgoingHook(t *testing.T) {
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
t.Fatal("should have failed - not creator or team admin")
@@ -475,9 +502,11 @@ func TestRegenOutgoingHookToken(t *testing.T) {
defer func() {
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks
utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks
utils.SetDefaultRolesBasedOnConfig()
}()
utils.Cfg.ServiceSettings.EnableOutgoingWebhooks = true
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = true
utils.SetDefaultRolesBasedOnConfig()
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
@@ -507,6 +536,7 @@ func TestRegenOutgoingHookToken(t *testing.T) {
}
*utils.Cfg.ServiceSettings.EnableOnlyAdminIntegrations = false
utils.SetDefaultRolesBasedOnConfig()
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)