github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/api4/branch.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"regexp"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"github.com/vnforks/kid/v5/audit"
    16  	"github.com/vnforks/kid/v5/model"
    17  )
    18  
    19  const (
    20  	MAX_ADD_MEMBERS_BATCH    = 20
    21  	MAXIMUM_BULK_IMPORT_SIZE = 10 * 1024 * 1024
    22  	groupIDsParamPattern     = "[^a-zA-Z0-9,]*"
    23  )
    24  
    25  var groupIDsQueryParamRegex *regexp.Regexp
    26  
    27  func init() {
    28  	groupIDsQueryParamRegex = regexp.MustCompile(groupIDsParamPattern)
    29  }
    30  
    31  func (api *API) InitBranch() {
    32  	api.BaseRoutes.Branches.Handle("", api.ApiSessionRequired(createBranch)).Methods("POST")
    33  	api.BaseRoutes.Branches.Handle("", api.ApiSessionRequired(getAllBranches)).Methods("GET")
    34  	api.BaseRoutes.Branches.Handle("/{branch_id:[A-Za-z0-9]+}/scheme", api.ApiSessionRequired(updateBranchScheme)).Methods("PUT")
    35  	api.BaseRoutes.BranchesForUser.Handle("", api.ApiSessionRequired(getBranchesForUser)).Methods("GET")
    36  
    37  	api.BaseRoutes.Branch.Handle("", api.ApiSessionRequired(getBranch)).Methods("GET")
    38  	api.BaseRoutes.Branch.Handle("", api.ApiSessionRequired(updateBranch)).Methods("PUT")
    39  	api.BaseRoutes.Branch.Handle("", api.ApiSessionRequired(deleteBranch)).Methods("DELETE")
    40  	api.BaseRoutes.Branch.Handle("/patch", api.ApiSessionRequired(patchBranch)).Methods("PUT")
    41  	api.BaseRoutes.Branch.Handle("/stats", api.ApiSessionRequired(getBranchStats)).Methods("GET")
    42  
    43  	api.BaseRoutes.Branch.Handle("/image", api.ApiSessionRequiredTrustRequester(getBranchIcon)).Methods("GET")
    44  	api.BaseRoutes.Branch.Handle("/image", api.ApiSessionRequired(setBranchIcon)).Methods("POST")
    45  	api.BaseRoutes.Branch.Handle("/image", api.ApiSessionRequired(removeBranchIcon)).Methods("DELETE")
    46  
    47  	api.BaseRoutes.BranchMembers.Handle("", api.ApiSessionRequired(getBranchMembers)).Methods("GET")
    48  	api.BaseRoutes.BranchMembers.Handle("/ids", api.ApiSessionRequired(getBranchMembersByIds)).Methods("POST")
    49  	api.BaseRoutes.BranchMembersForUser.Handle("", api.ApiSessionRequired(getBranchMembersForUser)).Methods("GET")
    50  	api.BaseRoutes.BranchMembers.Handle("", api.ApiSessionRequired(addBranchMember)).Methods("POST")
    51  	api.BaseRoutes.BranchMembers.Handle("/batch", api.ApiSessionRequired(addBranchMembers)).Methods("POST")
    52  	api.BaseRoutes.BranchMember.Handle("", api.ApiSessionRequired(removeBranchMember)).Methods("DELETE")
    53  
    54  	api.BaseRoutes.BranchByName.Handle("", api.ApiSessionRequired(getBranchByName)).Methods("GET")
    55  	api.BaseRoutes.BranchMember.Handle("", api.ApiSessionRequired(getBranchMember)).Methods("GET")
    56  	api.BaseRoutes.BranchByName.Handle("/exists", api.ApiSessionRequired(branchExists)).Methods("GET")
    57  	api.BaseRoutes.BranchMember.Handle("/roles", api.ApiSessionRequired(updateBranchMemberRoles)).Methods("PUT")
    58  	api.BaseRoutes.BranchMember.Handle("/schemeRoles", api.ApiSessionRequired(updateBranchMemberSchemeRoles)).Methods("PUT")
    59  }
    60  
    61  func createBranch(c *Context, w http.ResponseWriter, r *http.Request) {
    62  	branch := model.BranchFromJson(r.Body)
    63  	if branch == nil {
    64  		c.SetInvalidParam("branch")
    65  		return
    66  	}
    67  	branch.Email = strings.ToLower(branch.Email)
    68  
    69  	auditRec := c.MakeAuditRecord("createBranch", audit.Fail)
    70  	defer c.LogAuditRec(auditRec)
    71  	auditRec.AddMeta("branch_name", branch.Name)
    72  	auditRec.AddMeta("branch_display", branch.DisplayName)
    73  
    74  	if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_CREATE_BRANCH) {
    75  		c.Err = model.NewAppError("createBranch", "api.branch.is_branch_creation_allowed.disabled.app_error", nil, "", http.StatusForbidden)
    76  		return
    77  	}
    78  
    79  	rbranch, err := c.App.CreateBranchWithUser(branch, c.App.Session().UserId)
    80  	if err != nil {
    81  		c.Err = err
    82  		return
    83  	}
    84  
    85  	// Don't sanitize the branch here since the user will be a branch admin and their session won't reflect that yet
    86  
    87  	auditRec.Success()
    88  	auditRec.AddMeta("branch_id", rbranch.Id)
    89  
    90  	w.WriteHeader(http.StatusCreated)
    91  	w.Write([]byte(rbranch.ToJson()))
    92  }
    93  
    94  func getBranch(c *Context, w http.ResponseWriter, r *http.Request) {
    95  	c.RequireBranchId()
    96  	if c.Err != nil {
    97  		return
    98  	}
    99  
   100  	branch, err := c.App.GetBranch(c.Params.BranchId)
   101  	if err != nil {
   102  		c.Err = err
   103  		return
   104  	}
   105  
   106  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), branch.Id, model.PERMISSION_VIEW_BRANCH) {
   107  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   108  		return
   109  	}
   110  
   111  	c.App.SanitizeBranch(*c.App.Session(), branch)
   112  	w.Write([]byte(branch.ToJson()))
   113  }
   114  
   115  func getBranchByName(c *Context, w http.ResponseWriter, r *http.Request) {
   116  	c.RequireBranchName()
   117  	if c.Err != nil {
   118  		return
   119  	}
   120  
   121  	branch, err := c.App.GetBranchByName(c.Params.BranchName)
   122  	if err != nil {
   123  		c.Err = err
   124  		return
   125  	}
   126  
   127  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), branch.Id, model.PERMISSION_VIEW_BRANCH) {
   128  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   129  		return
   130  	}
   131  
   132  	c.App.SanitizeBranch(*c.App.Session(), branch)
   133  	w.Write([]byte(branch.ToJson()))
   134  }
   135  
   136  func updateBranch(c *Context, w http.ResponseWriter, r *http.Request) {
   137  	c.RequireBranchId()
   138  	if c.Err != nil {
   139  		return
   140  	}
   141  
   142  	branch := model.BranchFromJson(r.Body)
   143  
   144  	if branch == nil {
   145  		c.SetInvalidParam("branch")
   146  		return
   147  	}
   148  	branch.Email = strings.ToLower(branch.Email)
   149  
   150  	// The branch being updated in the payload must be the same one as indicated in the URL.
   151  	if branch.Id != c.Params.BranchId {
   152  		c.SetInvalidParam("id")
   153  		return
   154  	}
   155  
   156  	auditRec := c.MakeAuditRecord("updateBranch", audit.Fail)
   157  	defer c.LogAuditRec(auditRec)
   158  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   159  	auditRec.AddMeta("branch_name", branch.Name)
   160  	auditRec.AddMeta("branch_display", branch.DisplayName)
   161  
   162  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_BRANCH) {
   163  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH)
   164  		return
   165  	}
   166  
   167  	updatedBranch, err := c.App.UpdateBranch(branch)
   168  	if err != nil {
   169  		c.Err = err
   170  		return
   171  	}
   172  
   173  	auditRec.Success()
   174  
   175  	c.App.SanitizeBranch(*c.App.Session(), updatedBranch)
   176  	w.Write([]byte(updatedBranch.ToJson()))
   177  }
   178  
   179  func patchBranch(c *Context, w http.ResponseWriter, r *http.Request) {
   180  	c.RequireBranchId()
   181  	if c.Err != nil {
   182  		return
   183  	}
   184  
   185  	branch := model.BranchPatchFromJson(r.Body)
   186  
   187  	if branch == nil {
   188  		c.SetInvalidParam("branch")
   189  		return
   190  	}
   191  
   192  	auditRec := c.MakeAuditRecord("patchBranch", audit.Fail)
   193  	defer c.LogAuditRec(auditRec)
   194  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   195  
   196  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_BRANCH) {
   197  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH)
   198  		return
   199  	}
   200  
   201  	patchedBranch, err := c.App.PatchBranch(c.Params.BranchId, branch)
   202  
   203  	if err != nil {
   204  		c.Err = err
   205  		return
   206  	}
   207  
   208  	c.App.SanitizeBranch(*c.App.Session(), patchedBranch)
   209  
   210  	auditRec.Success()
   211  	auditRec.AddMeta("branch_name", patchedBranch.Name)
   212  	auditRec.AddMeta("branch_display", patchedBranch.DisplayName)
   213  	c.LogAudit("")
   214  
   215  	w.Write([]byte(patchedBranch.ToJson()))
   216  }
   217  
   218  func deleteBranch(c *Context, w http.ResponseWriter, r *http.Request) {
   219  	c.RequireBranchId()
   220  	if c.Err != nil {
   221  		return
   222  	}
   223  
   224  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_BRANCH) {
   225  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH)
   226  		return
   227  	}
   228  
   229  	auditRec := c.MakeAuditRecord("deleteBranch", audit.Fail)
   230  	defer c.LogAuditRec(auditRec)
   231  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   232  
   233  	var err *model.AppError
   234  	if c.Params.Permanent && *c.App.Config().ServiceSettings.EnableAPIBranchDeletion {
   235  		err = c.App.PermanentDeleteBranchId(c.Params.BranchId)
   236  	} else {
   237  		err = c.App.SoftDeleteBranch(c.Params.BranchId)
   238  	}
   239  
   240  	if err != nil {
   241  		c.Err = err
   242  		return
   243  	}
   244  
   245  	auditRec.Success()
   246  	ReturnStatusOK(w)
   247  }
   248  
   249  func getBranchesForUser(c *Context, w http.ResponseWriter, r *http.Request) {
   250  	c.RequireUserId()
   251  	if c.Err != nil {
   252  		return
   253  	}
   254  
   255  	if c.App.Session().UserId != c.Params.UserId && !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
   256  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   257  		return
   258  	}
   259  
   260  	branches, err := c.App.GetBranchesForUser(c.Params.UserId)
   261  	if err != nil {
   262  		c.Err = err
   263  		return
   264  	}
   265  
   266  	c.App.SanitizeBranches(*c.App.Session(), branches)
   267  	w.Write([]byte(model.BranchListToJson(branches)))
   268  }
   269  func getBranchMember(c *Context, w http.ResponseWriter, r *http.Request) {
   270  	c.RequireBranchId().RequireUserId()
   271  	if c.Err != nil {
   272  		return
   273  	}
   274  
   275  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_VIEW_BRANCH) {
   276  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   277  		return
   278  	}
   279  
   280  	canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, c.Params.UserId)
   281  	if err != nil {
   282  		c.Err = err
   283  		return
   284  	}
   285  
   286  	if !canSee {
   287  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   288  		return
   289  	}
   290  
   291  	branch, err := c.App.GetBranchMember(c.Params.BranchId, c.Params.UserId)
   292  	if err != nil {
   293  		c.Err = err
   294  		return
   295  	}
   296  
   297  	w.Write([]byte(branch.ToJson()))
   298  }
   299  
   300  func getBranchMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   301  	c.RequireBranchId()
   302  	if c.Err != nil {
   303  		return
   304  	}
   305  
   306  	sort := r.URL.Query().Get("sort")
   307  	excludeDeletedUsers := r.URL.Query().Get("exclude_deleted_users")
   308  	excludeDeletedUsersBool, _ := strconv.ParseBool(excludeDeletedUsers)
   309  
   310  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_VIEW_BRANCH) {
   311  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   312  		return
   313  	}
   314  
   315  	restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId)
   316  	if err != nil {
   317  		c.Err = err
   318  		return
   319  	}
   320  
   321  	branchMembersGetOptions := &model.BranchMembersGetOptions{
   322  		Sort:                sort,
   323  		ExcludeDeletedUsers: excludeDeletedUsersBool,
   324  		ViewRestrictions:    restrictions,
   325  	}
   326  
   327  	members, err := c.App.GetBranchMembers(c.Params.BranchId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, branchMembersGetOptions)
   328  	if err != nil {
   329  		c.Err = err
   330  		return
   331  	}
   332  
   333  	w.Write([]byte(model.BranchMembersToJson(members)))
   334  }
   335  
   336  func getBranchMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) {
   337  	c.RequireUserId()
   338  	if c.Err != nil {
   339  		return
   340  	}
   341  
   342  	if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) {
   343  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   344  		return
   345  	}
   346  
   347  	canSee, err := c.App.UserCanSeeOtherUser(c.App.Session().UserId, c.Params.UserId)
   348  	if err != nil {
   349  		c.Err = err
   350  		return
   351  	}
   352  
   353  	if !canSee {
   354  		c.SetPermissionError(model.PERMISSION_VIEW_MEMBERS)
   355  		return
   356  	}
   357  
   358  	members, err := c.App.GetBranchMembersForUser(c.Params.UserId)
   359  	if err != nil {
   360  		c.Err = err
   361  		return
   362  	}
   363  
   364  	w.Write([]byte(model.BranchMembersToJson(members)))
   365  }
   366  
   367  func getBranchMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
   368  	c.RequireBranchId()
   369  	if c.Err != nil {
   370  		return
   371  	}
   372  
   373  	userIds := model.ArrayFromJson(r.Body)
   374  
   375  	if len(userIds) == 0 {
   376  		c.SetInvalidParam("user_ids")
   377  		return
   378  	}
   379  
   380  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_VIEW_BRANCH) {
   381  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   382  		return
   383  	}
   384  
   385  	restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId)
   386  	if err != nil {
   387  		c.Err = err
   388  		return
   389  	}
   390  
   391  	members, err := c.App.GetBranchMembersByIds(c.Params.BranchId, userIds, restrictions)
   392  	if err != nil {
   393  		c.Err = err
   394  		return
   395  	}
   396  
   397  	w.Write([]byte(model.BranchMembersToJson(members)))
   398  }
   399  
   400  func addBranchMember(c *Context, w http.ResponseWriter, r *http.Request) {
   401  	c.RequireBranchId()
   402  	if c.Err != nil {
   403  		return
   404  	}
   405  
   406  	var err *model.AppError
   407  	member := model.BranchMemberFromJson(r.Body)
   408  	if member.BranchId != c.Params.BranchId {
   409  		c.SetInvalidParam("branch_id")
   410  		return
   411  	}
   412  
   413  	if len(member.UserId) != 26 {
   414  		c.SetInvalidParam("user_id")
   415  		return
   416  	}
   417  
   418  	auditRec := c.MakeAuditRecord("addBranchMember", audit.Fail)
   419  	defer c.LogAuditRec(auditRec)
   420  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   421  	auditRec.AddMeta("add_user_id", member.UserId)
   422  
   423  	if member.UserId == c.App.Session().UserId {
   424  		_, err = c.App.GetBranch(member.BranchId)
   425  		if err != nil {
   426  			c.Err = err
   427  			return
   428  		}
   429  
   430  	} else {
   431  		if !c.App.SessionHasPermissionToBranch(*c.App.Session(), member.BranchId, model.PERMISSION_ADD_USER_TO_BRANCH) {
   432  			c.SetPermissionError(model.PERMISSION_ADD_USER_TO_BRANCH)
   433  			return
   434  		}
   435  	}
   436  
   437  	branch, err := c.App.GetBranch(member.BranchId)
   438  	if err != nil {
   439  		c.Err = err
   440  		return
   441  	}
   442  	auditRec.AddMeta("branch_name", branch.Name)
   443  	auditRec.AddMeta("branch_display", branch.DisplayName)
   444  
   445  	member, err = c.App.AddBranchMember(member.BranchId, member.UserId)
   446  
   447  	if err != nil {
   448  		c.Err = err
   449  		return
   450  	}
   451  
   452  	auditRec.Success()
   453  
   454  	w.WriteHeader(http.StatusCreated)
   455  	w.Write([]byte(member.ToJson()))
   456  }
   457  
   458  func addBranchMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   459  	graceful := r.URL.Query().Get("graceful") != ""
   460  
   461  	c.RequireBranchId()
   462  	if c.Err != nil {
   463  		return
   464  	}
   465  
   466  	var err *model.AppError
   467  	members := model.BranchMembersFromJson(r.Body)
   468  
   469  	if len(members) > MAX_ADD_MEMBERS_BATCH {
   470  		c.SetInvalidParam("too many members in batch")
   471  		return
   472  	}
   473  
   474  	if len(members) == 0 {
   475  		c.SetInvalidParam("no members in batch")
   476  		return
   477  	}
   478  
   479  	auditRec := c.MakeAuditRecord("addBranchMembers", audit.Fail)
   480  	defer c.LogAuditRec(auditRec)
   481  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   482  	auditRec.AddMeta("count", len(members))
   483  
   484  	var memberIDs []string
   485  	for _, member := range members {
   486  		memberIDs = append(memberIDs, member.UserId)
   487  	}
   488  	auditRec.AddMeta("user_ids", memberIDs)
   489  
   490  	branch, err := c.App.GetBranch(c.Params.BranchId)
   491  	if err != nil {
   492  		c.Err = err
   493  		return
   494  	}
   495  	auditRec.AddMeta("branch_name", branch.Name)
   496  	auditRec.AddMeta("branch_display", branch.DisplayName)
   497  
   498  	var userIds []string
   499  	for _, member := range members {
   500  		if member.BranchId != c.Params.BranchId {
   501  			c.SetInvalidParam("branch_id for member with user_id=" + member.UserId)
   502  			return
   503  		}
   504  
   505  		if len(member.UserId) != 26 {
   506  			c.SetInvalidParam("user_id")
   507  			return
   508  		}
   509  
   510  		userIds = append(userIds, member.UserId)
   511  	}
   512  
   513  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_ADD_USER_TO_BRANCH) {
   514  		c.SetPermissionError(model.PERMISSION_ADD_USER_TO_BRANCH)
   515  		return
   516  	}
   517  
   518  	membersWithErrors, err := c.App.AddBranchMembers(c.Params.BranchId, userIds, c.App.Session().UserId, graceful)
   519  
   520  	if membersWithErrors != nil {
   521  		errList := make([]string, 0, len(membersWithErrors))
   522  		for _, m := range membersWithErrors {
   523  			if m.Error != nil {
   524  				errList = append(errList, model.BranchMemberWithErrorToString(m))
   525  			}
   526  		}
   527  		auditRec.AddMeta("errors", errList)
   528  	}
   529  	if err != nil {
   530  		c.Err = err
   531  		return
   532  	}
   533  
   534  	auditRec.Success()
   535  
   536  	w.WriteHeader(http.StatusCreated)
   537  
   538  	if graceful {
   539  		// in 'graceful' mode we allow a different return value, notifying the client which users were not added
   540  		w.Write([]byte(model.BranchMembersWithErrorToJson(membersWithErrors)))
   541  	} else {
   542  		w.Write([]byte(model.BranchMembersToJson(model.BranchMembersWithErrorToBranchMembers(membersWithErrors))))
   543  	}
   544  
   545  }
   546  
   547  func removeBranchMember(c *Context, w http.ResponseWriter, r *http.Request) {
   548  	c.RequireBranchId().RequireUserId()
   549  	if c.Err != nil {
   550  		return
   551  	}
   552  
   553  	auditRec := c.MakeAuditRecord("removeBranchMember", audit.Fail)
   554  	defer c.LogAuditRec(auditRec)
   555  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   556  
   557  	if c.App.Session().UserId != c.Params.UserId {
   558  		if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_REMOVE_USER_FROM_BRANCH) {
   559  			c.SetPermissionError(model.PERMISSION_REMOVE_USER_FROM_BRANCH)
   560  			return
   561  		}
   562  	}
   563  
   564  	branch, err := c.App.GetBranch(c.Params.BranchId)
   565  	if err != nil {
   566  		c.Err = err
   567  		return
   568  	}
   569  	auditRec.AddMeta("branch_name", branch.Name)
   570  	auditRec.AddMeta("branch_display", branch.DisplayName)
   571  
   572  	user, err := c.App.GetUser(c.Params.UserId)
   573  	if err != nil {
   574  		c.Err = err
   575  		return
   576  	}
   577  	auditRec.AddMeta("remove_user_id", user.Id)
   578  
   579  	if c.Params.UserId != c.App.Session().UserId {
   580  		c.Err = model.NewAppError("removeBranchMember", "api.branch.remove_member.group_constrained.app_error", nil, "", http.StatusBadRequest)
   581  		return
   582  	}
   583  
   584  	if err := c.App.RemoveUserFromBranch(c.Params.BranchId, c.Params.UserId, c.App.Session().UserId); err != nil {
   585  		c.Err = err
   586  		return
   587  	}
   588  
   589  	auditRec.Success()
   590  	ReturnStatusOK(w)
   591  }
   592  
   593  func getBranchStats(c *Context, w http.ResponseWriter, r *http.Request) {
   594  	c.RequireBranchId()
   595  	if c.Err != nil {
   596  		return
   597  	}
   598  
   599  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_VIEW_BRANCH) {
   600  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   601  		return
   602  	}
   603  
   604  	restrictions, err := c.App.GetViewUsersRestrictions(c.App.Session().UserId)
   605  	if err != nil {
   606  		c.Err = err
   607  		return
   608  	}
   609  
   610  	stats, err := c.App.GetBranchStats(c.Params.BranchId, restrictions)
   611  	if err != nil {
   612  		c.Err = err
   613  		return
   614  	}
   615  
   616  	w.Write([]byte(stats.ToJson()))
   617  }
   618  
   619  func updateBranchMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   620  	c.RequireBranchId().RequireUserId()
   621  	if c.Err != nil {
   622  		return
   623  	}
   624  
   625  	props := model.MapFromJson(r.Body)
   626  
   627  	newRoles := props["roles"]
   628  	if !model.IsValidUserRoles(newRoles) {
   629  		c.SetInvalidParam("branch_member_roles")
   630  		return
   631  	}
   632  
   633  	auditRec := c.MakeAuditRecord("updateBranchMemberRoles", audit.Fail)
   634  	defer c.LogAuditRec(auditRec)
   635  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   636  	auditRec.AddMeta("update_user_id", c.Params.UserId)
   637  
   638  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_BRANCH_ROLES) {
   639  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH_ROLES)
   640  		return
   641  	}
   642  
   643  	if _, err := c.App.UpdateBranchMemberRoles(c.Params.BranchId, c.Params.UserId, newRoles); err != nil {
   644  		c.Err = err
   645  		return
   646  	}
   647  
   648  	auditRec.Success()
   649  	ReturnStatusOK(w)
   650  }
   651  
   652  func updateBranchMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   653  	c.RequireBranchId().RequireUserId()
   654  	if c.Err != nil {
   655  		return
   656  	}
   657  
   658  	schemeRoles := model.SchemeRolesFromJson(r.Body)
   659  	if schemeRoles == nil {
   660  		c.SetInvalidParam("scheme_roles")
   661  		return
   662  	}
   663  
   664  	auditRec := c.MakeAuditRecord("updateBranchMemberSchemeRoles", audit.Fail)
   665  	defer c.LogAuditRec(auditRec)
   666  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   667  	auditRec.AddMeta("update_user_id", c.Params.UserId)
   668  	auditRec.AddMeta("new_scheme_admin", schemeRoles.SchemeAdmin)
   669  	auditRec.AddMeta("new_scheme_user", schemeRoles.SchemeUser)
   670  
   671  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_BRANCH_ROLES) {
   672  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH_ROLES)
   673  		return
   674  	}
   675  
   676  	if _, err := c.App.UpdateBranchMemberSchemeRoles(c.Params.BranchId, c.Params.UserId, schemeRoles.SchemeUser, schemeRoles.SchemeAdmin); err != nil {
   677  		c.Err = err
   678  		return
   679  	}
   680  
   681  	auditRec.Success()
   682  	ReturnStatusOK(w)
   683  }
   684  
   685  func getAllBranches(c *Context, w http.ResponseWriter, r *http.Request) {
   686  	branches := []*model.Branch{}
   687  	var err *model.AppError
   688  	var branchesWithCount *model.BranchesWithCount
   689  
   690  	// list := c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_LIST_BRANCHES)
   691  	if c.Params.IncludeTotalCount {
   692  		branchesWithCount, err = c.App.GetAllBranchesPageWithCount(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
   693  	} else {
   694  		branches, err = c.App.GetAllBranchesPage(c.Params.Page*c.Params.PerPage, c.Params.PerPage)
   695  	}
   696  
   697  	if err != nil {
   698  		c.Err = err
   699  		return
   700  	}
   701  
   702  	c.App.SanitizeBranches(*c.App.Session(), branches)
   703  
   704  	var resBody []byte
   705  
   706  	if c.Params.IncludeTotalCount {
   707  		resBody = model.BranchesWithCountToJson(branchesWithCount)
   708  	} else {
   709  		resBody = []byte(model.BranchListToJson(branches))
   710  	}
   711  
   712  	w.Write(resBody)
   713  }
   714  
   715  func branchExists(c *Context, w http.ResponseWriter, r *http.Request) {
   716  	c.RequireBranchName()
   717  	if c.Err != nil {
   718  		return
   719  	}
   720  
   721  	branch, err := c.App.GetBranchByName(c.Params.BranchName)
   722  	if err != nil && err.StatusCode != http.StatusNotFound {
   723  		c.Err = err
   724  		return
   725  	}
   726  
   727  	exists := false
   728  
   729  	if branch != nil {
   730  		var branchMember *model.BranchMember
   731  		branchMember, err = c.App.GetBranchMember(branch.Id, c.App.Session().UserId)
   732  		if err != nil && err.StatusCode != http.StatusNotFound {
   733  			c.Err = err
   734  			return
   735  		}
   736  
   737  		// Verify that the user can see the branch (be a member or have the permission to list the branch)
   738  		if branchMember != nil && branchMember.DeleteAt == 0 {
   739  			exists = true
   740  		}
   741  	}
   742  
   743  	resp := map[string]bool{"exists": exists}
   744  	w.Write([]byte(model.MapBoolToJson(resp)))
   745  }
   746  
   747  func getBranchIcon(c *Context, w http.ResponseWriter, r *http.Request) {
   748  	c.RequireBranchId()
   749  	if c.Err != nil {
   750  		return
   751  	}
   752  
   753  	branch, err := c.App.GetBranch(c.Params.BranchId)
   754  
   755  	if err != nil {
   756  		c.Err = err
   757  		return
   758  	}
   759  
   760  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_VIEW_BRANCH) {
   761  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   762  		return
   763  	}
   764  
   765  	etag := strconv.FormatInt(branch.LastBranchIconUpdate, 10)
   766  
   767  	if c.HandleEtag(etag, "Get Branch Icon", w, r) {
   768  		return
   769  	}
   770  
   771  	img, err := c.App.GetBranchIcon(branch)
   772  	if err != nil {
   773  		c.Err = err
   774  		return
   775  	}
   776  
   777  	w.Header().Set("Content-Type", "image/png")
   778  	w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%v, public", 24*60*60)) // 24 hrs
   779  	w.Header().Set(model.HEADER_ETAG_SERVER, etag)
   780  	w.Write(img)
   781  }
   782  
   783  func setBranchIcon(c *Context, w http.ResponseWriter, r *http.Request) {
   784  	defer io.Copy(ioutil.Discard, r.Body)
   785  
   786  	c.RequireBranchId()
   787  	if c.Err != nil {
   788  		return
   789  	}
   790  
   791  	auditRec := c.MakeAuditRecord("setBranchIcon", audit.Fail)
   792  	defer c.LogAuditRec(auditRec)
   793  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   794  
   795  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_BRANCH) {
   796  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH)
   797  		return
   798  	}
   799  
   800  	if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize {
   801  		c.Err = model.NewAppError("setBranchIcon", "api.branch.set_branch_icon.too_large.app_error", nil, "", http.StatusBadRequest)
   802  		return
   803  	}
   804  
   805  	if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil {
   806  		c.Err = model.NewAppError("setBranchIcon", "api.branch.set_branch_icon.parse.app_error", nil, err.Error(), http.StatusBadRequest)
   807  		return
   808  	}
   809  
   810  	m := r.MultipartForm
   811  
   812  	imageArray, ok := m.File["image"]
   813  	if !ok {
   814  		c.Err = model.NewAppError("setBranchIcon", "api.branch.set_branch_icon.no_file.app_error", nil, "", http.StatusBadRequest)
   815  		return
   816  	}
   817  
   818  	if len(imageArray) <= 0 {
   819  		c.Err = model.NewAppError("setBranchIcon", "api.branch.set_branch_icon.array.app_error", nil, "", http.StatusBadRequest)
   820  		return
   821  	}
   822  
   823  	imageData := imageArray[0]
   824  
   825  	if err := c.App.SetBranchIcon(c.Params.BranchId, imageData); err != nil {
   826  		c.Err = err
   827  		return
   828  	}
   829  
   830  	auditRec.Success()
   831  	c.LogAudit("")
   832  
   833  	ReturnStatusOK(w)
   834  }
   835  
   836  func removeBranchIcon(c *Context, w http.ResponseWriter, r *http.Request) {
   837  	c.RequireBranchId()
   838  	if c.Err != nil {
   839  		return
   840  	}
   841  
   842  	auditRec := c.MakeAuditRecord("removeBranchIcon", audit.Fail)
   843  	defer c.LogAuditRec(auditRec)
   844  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   845  
   846  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_BRANCH) {
   847  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH)
   848  		return
   849  	}
   850  
   851  	if err := c.App.RemoveBranchIcon(c.Params.BranchId); err != nil {
   852  		c.Err = err
   853  		return
   854  	}
   855  
   856  	auditRec.Success()
   857  	c.LogAudit("")
   858  
   859  	ReturnStatusOK(w)
   860  }
   861  
   862  func updateBranchScheme(c *Context, w http.ResponseWriter, r *http.Request) {
   863  	c.RequireBranchId()
   864  	if c.Err != nil {
   865  		return
   866  	}
   867  
   868  	schemeID := model.SchemeIDFromJson(r.Body)
   869  	if schemeID == nil || (len(*schemeID) != 26 && *schemeID != "") {
   870  		c.SetInvalidParam("scheme_id")
   871  		return
   872  	}
   873  
   874  	auditRec := c.MakeAuditRecord("updateBranchScheme", audit.Fail)
   875  	defer c.LogAuditRec(auditRec)
   876  	auditRec.AddMeta("branch_id", c.Params.BranchId)
   877  
   878  	if c.App.License() == nil {
   879  		c.Err = model.NewAppError("Api4.UpdateBranchScheme", "api.branch.update_branch_scheme.license.error", nil, "", http.StatusNotImplemented)
   880  		return
   881  	}
   882  
   883  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_SYSTEM) {
   884  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   885  		return
   886  	}
   887  
   888  	if *schemeID != "" {
   889  		scheme, err := c.App.GetScheme(*schemeID)
   890  		if err != nil {
   891  			c.Err = err
   892  			return
   893  		}
   894  		auditRec.AddMeta("scheme_id", scheme.Id)
   895  		auditRec.AddMeta("scheme_name", scheme.Name)
   896  		auditRec.AddMeta("scheme_display", scheme.DisplayName)
   897  
   898  		if scheme.Scope != model.SCHEME_SCOPE_BRANCH {
   899  			c.Err = model.NewAppError("Api4.UpdateBranchScheme", "api.branch.update_branch_scheme.scheme_scope.error", nil, "", http.StatusBadRequest)
   900  			return
   901  		}
   902  	}
   903  
   904  	branch, err := c.App.GetBranch(c.Params.BranchId)
   905  	if err != nil {
   906  		c.Err = err
   907  		return
   908  	}
   909  	auditRec.AddMeta("branch_name", branch.Name)
   910  	auditRec.AddMeta("branch_display", branch.DisplayName)
   911  
   912  	branch.SchemeId = schemeID
   913  
   914  	_, err = c.App.UpdateBranchScheme(branch)
   915  	if err != nil {
   916  		c.Err = err
   917  		return
   918  	}
   919  
   920  	auditRec.Success()
   921  	ReturnStatusOK(w)
   922  }