github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/api4/class.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  	"encoding/json"
     8  	"net/http"
     9  
    10  	"github.com/vnforks/kid/v5/audit"
    11  	"github.com/vnforks/kid/v5/model"
    12  	"github.com/vnforks/kid/v5/store"
    13  )
    14  
    15  func (api *API) InitClass() {
    16  	api.BaseRoutes.Classes.Handle("", api.ApiSessionRequired(getAllClasses)).Methods("GET")
    17  	api.BaseRoutes.Classes.Handle("", api.ApiSessionRequired(createClass)).Methods("POST")
    18  	api.BaseRoutes.Classes.Handle("/{class_id:[A-Za-z0-9]+}/scheme", api.ApiSessionRequired(updateClassScheme)).Methods("PUT")
    19  
    20  	api.BaseRoutes.ClassesForBranch.Handle("/deleted", api.ApiSessionRequired(getDeletedClassesForBranch)).Methods("GET")
    21  	api.BaseRoutes.User.Handle("/branches/{branch_id:[A-Za-z0-9]+}/classes", api.ApiSessionRequired(getClassesForBranchForUser)).Methods("GET")
    22  
    23  	api.BaseRoutes.Class.Handle("", api.ApiSessionRequired(getClass)).Methods("GET")
    24  	api.BaseRoutes.Class.Handle("", api.ApiSessionRequired(updateClass)).Methods("PUT")
    25  	api.BaseRoutes.Class.Handle("/patch", api.ApiSessionRequired(patchClass)).Methods("PUT")
    26  	api.BaseRoutes.Class.Handle("/restore", api.ApiSessionRequired(restoreClass)).Methods("POST")
    27  	api.BaseRoutes.Class.Handle("", api.ApiSessionRequired(deleteClass)).Methods("DELETE")
    28  	api.BaseRoutes.Class.Handle("/timezones", api.ApiSessionRequired(getClassMembersTimezones)).Methods("GET")
    29  
    30  	api.BaseRoutes.ClassByName.Handle("", api.ApiSessionRequired(getClassByName)).Methods("GET")
    31  	api.BaseRoutes.ClassByNameForBranchName.Handle("", api.ApiSessionRequired(getClassByNameForBranchName)).Methods("GET")
    32  
    33  	api.BaseRoutes.ClassMembers.Handle("", api.ApiSessionRequired(getClassMembers)).Methods("GET")
    34  	api.BaseRoutes.ClassMembers.Handle("/ids", api.ApiSessionRequired(getClassMembersByIds)).Methods("POST")
    35  	api.BaseRoutes.ClassMembers.Handle("", api.ApiSessionRequired(addClassMember)).Methods("POST")
    36  	api.BaseRoutes.ClassMembersForUser.Handle("", api.ApiSessionRequired(getClassMembersForUser)).Methods("GET")
    37  	api.BaseRoutes.ClassMember.Handle("", api.ApiSessionRequired(getClassMember)).Methods("GET")
    38  	api.BaseRoutes.ClassMember.Handle("", api.ApiSessionRequired(removeClassMember)).Methods("DELETE")
    39  	api.BaseRoutes.ClassMember.Handle("/roles", api.ApiSessionRequired(updateClassMemberRoles)).Methods("PUT")
    40  	api.BaseRoutes.ClassMember.Handle("/schemeRoles", api.ApiSessionRequired(updateClassMemberSchemeRoles)).Methods("PUT")
    41  	api.BaseRoutes.ClassMember.Handle("/notify_props", api.ApiSessionRequired(updateClassMemberNotifyProps)).Methods("PUT")
    42  
    43  	api.BaseRoutes.ClassModerations.Handle("", api.ApiSessionRequired(getClassModerations)).Methods("GET")
    44  	api.BaseRoutes.ClassModerations.Handle("/patch", api.ApiSessionRequired(patchClassModerations)).Methods("PUT")
    45  }
    46  
    47  func createClass(c *Context, w http.ResponseWriter, r *http.Request) {
    48  	class := model.ClassFromJson(r.Body)
    49  	if class == nil {
    50  		c.SetInvalidParam("class")
    51  		return
    52  	}
    53  
    54  	auditRec := c.MakeAuditRecord("createClass", audit.Fail)
    55  	defer c.LogAuditRec(auditRec)
    56  	auditRec.AddMeta("class_name", class.Name)
    57  
    58  	sc, err := c.App.CreateClassWithUser(class, c.App.Session().UserId)
    59  	if err != nil {
    60  		c.Err = err
    61  		return
    62  	}
    63  
    64  	auditRec.Success()
    65  	auditRec.AddMeta("class_id", sc.Id)
    66  	c.LogAudit("name=" + class.Name)
    67  
    68  	w.WriteHeader(http.StatusCreated)
    69  	w.Write([]byte(sc.ToJson()))
    70  }
    71  
    72  func updateClass(c *Context, w http.ResponseWriter, r *http.Request) {
    73  	c.RequireClassId()
    74  	if c.Err != nil {
    75  		return
    76  	}
    77  
    78  	class := model.ClassFromJson(r.Body)
    79  
    80  	if class == nil {
    81  		c.SetInvalidParam("class")
    82  		return
    83  	}
    84  
    85  	// The class being updated in the payload must be the same one as indicated in the URL.
    86  	if class.Id != c.Params.ClassId {
    87  		c.SetInvalidParam("class_id")
    88  		return
    89  	}
    90  
    91  	auditRec := c.MakeAuditRecord("updateClass", audit.Fail)
    92  	defer c.LogAuditRec(auditRec)
    93  	auditRec.AddMeta("class_id", class.Id)
    94  
    95  	originalOldClass, err := c.App.GetClass(class.Id)
    96  	if err != nil {
    97  		c.Err = err
    98  		return
    99  	}
   100  	oldClass := originalOldClass.DeepCopy()
   101  
   102  	auditRec.AddMeta("class_name", oldClass.Name)
   103  
   104  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_MANAGE_CLASS) {
   105  		c.SetPermissionError(model.PERMISSION_MANAGE_CLASS)
   106  		return
   107  	}
   108  
   109  	if oldClass.DeleteAt > 0 {
   110  		c.Err = model.NewAppError("updateClass", "api.class.update_class.deleted.app_error", nil, "", http.StatusBadRequest)
   111  		return
   112  	}
   113  
   114  	if oldClass.Name == model.DEFAULT_CLASS {
   115  		if len(class.Name) > 0 && class.Name != oldClass.Name {
   116  			c.Err = model.NewAppError("updateClass", "api.class.update_class.tried.app_error", map[string]interface{}{"Class": model.DEFAULT_CLASS}, "", http.StatusBadRequest)
   117  			return
   118  		}
   119  	}
   120  
   121  	oldClass.Header = class.Header
   122  	oldClass.Purpose = class.Purpose
   123  
   124  	if len(class.DisplayName) > 0 {
   125  		oldClass.DisplayName = class.DisplayName
   126  	}
   127  
   128  	if len(class.Name) > 0 {
   129  		oldClass.Name = class.Name
   130  		auditRec.AddMeta("new_class_name", oldClass.Name)
   131  	}
   132  
   133  	if _, err := c.App.UpdateClass(oldClass); err != nil {
   134  		c.Err = err
   135  		return
   136  	}
   137  
   138  	auditRec.Success()
   139  	c.LogAudit("name=" + class.Name)
   140  
   141  	w.Write([]byte(oldClass.ToJson()))
   142  }
   143  
   144  func patchClass(c *Context, w http.ResponseWriter, r *http.Request) {
   145  	c.RequireClassId()
   146  	if c.Err != nil {
   147  		return
   148  	}
   149  
   150  	patch := model.ClassPatchFromJson(r.Body)
   151  	if patch == nil {
   152  		c.SetInvalidParam("class")
   153  		return
   154  	}
   155  
   156  	originalOldClass, err := c.App.GetClass(c.Params.ClassId)
   157  	if err != nil {
   158  		c.Err = err
   159  		return
   160  	}
   161  	oldClass := originalOldClass.DeepCopy()
   162  
   163  	auditRec := c.MakeAuditRecord("patchClass", audit.Fail)
   164  	defer c.LogAuditRec(auditRec)
   165  	auditRec.AddMeta("class_id", oldClass.Id)
   166  	auditRec.AddMeta("class_name", oldClass.Name)
   167  
   168  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_MANAGE_CLASS) {
   169  		c.SetPermissionError(model.PERMISSION_MANAGE_CLASS)
   170  		return
   171  	}
   172  
   173  	rclass, err := c.App.PatchClass(oldClass, patch, c.App.Session().UserId)
   174  	if err != nil {
   175  		c.Err = err
   176  		return
   177  	}
   178  
   179  	auditRec.Success()
   180  	c.LogAudit("")
   181  
   182  	w.Write([]byte(rclass.ToJson()))
   183  }
   184  
   185  func restoreClass(c *Context, w http.ResponseWriter, r *http.Request) {
   186  	c.RequireClassId()
   187  	if c.Err != nil {
   188  		return
   189  	}
   190  
   191  	class, err := c.App.GetClass(c.Params.ClassId)
   192  	if err != nil {
   193  		c.Err = err
   194  		return
   195  	}
   196  	branchId := class.BranchId
   197  
   198  	auditRec := c.MakeAuditRecord("restoreClass", audit.Fail)
   199  	defer c.LogAuditRec(auditRec)
   200  	auditRec.AddMeta("class_id", class.Id)
   201  	auditRec.AddMeta("class_name", class.Name)
   202  
   203  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), branchId, model.PERMISSION_MANAGE_BRANCH) {
   204  		c.SetPermissionError(model.PERMISSION_MANAGE_BRANCH)
   205  		return
   206  	}
   207  
   208  	class, err = c.App.RestoreClass(class, c.App.Session().UserId)
   209  	if err != nil {
   210  		c.Err = err
   211  		return
   212  	}
   213  
   214  	auditRec.Success()
   215  	c.LogAudit("name=" + class.Name)
   216  
   217  	w.Write([]byte(class.ToJson()))
   218  }
   219  
   220  func getClass(c *Context, w http.ResponseWriter, r *http.Request) {
   221  	c.RequireClassId()
   222  	if c.Err != nil {
   223  		return
   224  	}
   225  
   226  	class, err := c.App.GetClass(c.Params.ClassId)
   227  	if err != nil {
   228  		c.Err = err
   229  		return
   230  	}
   231  
   232  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_READ_CLASS) {
   233  		c.SetPermissionError(model.PERMISSION_READ_CLASS)
   234  		return
   235  	}
   236  
   237  	w.Write([]byte(class.ToJson()))
   238  }
   239  
   240  func getAllClasses(c *Context, w http.ResponseWriter, r *http.Request) {
   241  	if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
   242  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   243  		return
   244  	}
   245  
   246  	opts := model.ClassSearchOpts{
   247  		NotAssociatedToGroup:  c.Params.NotAssociatedToGroup,
   248  		ExcludeDefaultClasses: c.Params.ExcludeDefaultClasses,
   249  	}
   250  
   251  	classes, err := c.App.GetAllClasses(c.Params.Page, c.Params.PerPage, opts)
   252  	if err != nil {
   253  		c.Err = err
   254  		return
   255  	}
   256  
   257  	var payload []byte
   258  	if c.Params.IncludeTotalCount {
   259  		totalCount, err := c.App.GetAllClassesCount(opts)
   260  		if err != nil {
   261  			c.Err = err
   262  			return
   263  		}
   264  		cwc := &model.ClassesWithCount{
   265  			Classes:    classes,
   266  			TotalCount: totalCount,
   267  		}
   268  		payload = cwc.ToJson()
   269  	} else {
   270  		payload = []byte(classes.ToJson())
   271  	}
   272  
   273  	w.Write(payload)
   274  }
   275  
   276  func getDeletedClassesForBranch(c *Context, w http.ResponseWriter, r *http.Request) {
   277  	c.RequireBranchId()
   278  	if c.Err != nil {
   279  		return
   280  	}
   281  
   282  	classes, err := c.App.GetDeletedClasses(c.Params.BranchId, c.Params.Page*c.Params.PerPage, c.Params.PerPage, c.App.Session().UserId)
   283  	if err != nil {
   284  		c.Err = err
   285  		return
   286  	}
   287  
   288  	w.Write([]byte(classes.ToJson()))
   289  }
   290  
   291  func getClassesForBranchForUser(c *Context, w http.ResponseWriter, r *http.Request) {
   292  	c.RequireUserId().RequireBranchId()
   293  	if c.Err != nil {
   294  		return
   295  	}
   296  
   297  	if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) {
   298  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   299  		return
   300  	}
   301  
   302  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_VIEW_BRANCH) {
   303  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   304  		return
   305  	}
   306  
   307  	classes, err := c.App.GetClassesForUser(c.Params.BranchId, c.Params.UserId, c.Params.IncludeDeleted)
   308  	if err != nil {
   309  		c.Err = err
   310  		return
   311  	}
   312  
   313  	if c.HandleEtag(classes.Etag(), "Get Classes", w, r) {
   314  		return
   315  	}
   316  	w.Header().Set(model.HEADER_ETAG_SERVER, classes.Etag())
   317  	w.Write([]byte(classes.ToJson()))
   318  }
   319  
   320  func deleteClass(c *Context, w http.ResponseWriter, r *http.Request) {
   321  	c.RequireClassId()
   322  	if c.Err != nil {
   323  		return
   324  	}
   325  
   326  	class, err := c.App.GetClass(c.Params.ClassId)
   327  	if err != nil {
   328  		c.Err = err
   329  		return
   330  	}
   331  
   332  	auditRec := c.MakeAuditRecord("deleteClass", audit.Fail)
   333  	defer c.LogAuditRec(auditRec)
   334  	auditRec.AddMeta("class_id", class.Id)
   335  	auditRec.AddMeta("class_name", class.Name)
   336  
   337  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), class.Id, model.PERMISSION_DELETE_CLASS) {
   338  		c.SetPermissionError(model.PERMISSION_DELETE_CLASS)
   339  		return
   340  	}
   341  
   342  	err = c.App.DeleteClass(class, c.App.Session().UserId)
   343  	if err != nil {
   344  		c.Err = err
   345  		return
   346  	}
   347  
   348  	auditRec.Success()
   349  	c.LogAudit("name=" + class.Name)
   350  
   351  	ReturnStatusOK(w)
   352  }
   353  
   354  func getClassByName(c *Context, w http.ResponseWriter, r *http.Request) {
   355  	c.RequireBranchId().RequireClassName()
   356  	if c.Err != nil {
   357  		return
   358  	}
   359  
   360  	includeDeleted := r.URL.Query().Get("include_deleted") == "true"
   361  
   362  	class, err := c.App.GetClassByName(c.Params.ClassName, c.Params.BranchId, includeDeleted)
   363  	if err != nil {
   364  		c.Err = err
   365  		return
   366  	}
   367  
   368  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), class.Id, model.PERMISSION_READ_CLASS) {
   369  		c.Err = model.NewAppError("getClassByName", store.MISSING_CLASS_ERROR, nil, "branchId="+class.BranchId+", "+"name="+class.Name+"", http.StatusNotFound)
   370  		return
   371  	}
   372  
   373  	w.Write([]byte(class.ToJson()))
   374  }
   375  
   376  func getClassByNameForBranchName(c *Context, w http.ResponseWriter, r *http.Request) {
   377  	c.RequireBranchName().RequireClassName()
   378  	if c.Err != nil {
   379  		return
   380  	}
   381  
   382  	includeDeleted := r.URL.Query().Get("include_deleted") == "true"
   383  
   384  	class, err := c.App.GetClassByNameForBranchName(c.Params.ClassName, c.Params.BranchName, includeDeleted)
   385  	if err != nil {
   386  		c.Err = err
   387  		return
   388  	}
   389  
   390  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), class.Id, model.PERMISSION_READ_CLASS) {
   391  		c.Err = model.NewAppError("getClassByNameForBranchName", store.MISSING_CLASS_ERROR, nil, "branchId="+class.BranchId+", "+"name="+class.Name+"", http.StatusNotFound)
   392  		return
   393  	}
   394  
   395  	w.Write([]byte(class.ToJson()))
   396  }
   397  
   398  func getClassMembers(c *Context, w http.ResponseWriter, r *http.Request) {
   399  	c.RequireClassId()
   400  	if c.Err != nil {
   401  		return
   402  	}
   403  
   404  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_READ_CLASS) {
   405  		c.SetPermissionError(model.PERMISSION_READ_CLASS)
   406  		return
   407  	}
   408  
   409  	members, err := c.App.GetClassMembersPage(c.Params.ClassId, c.Params.Page, c.Params.PerPage)
   410  	if err != nil {
   411  		c.Err = err
   412  		return
   413  	}
   414  
   415  	w.Write([]byte(members.ToJson()))
   416  }
   417  
   418  func getClassMembersTimezones(c *Context, w http.ResponseWriter, r *http.Request) {
   419  	c.RequireClassId()
   420  	if c.Err != nil {
   421  		return
   422  	}
   423  
   424  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_READ_CLASS) {
   425  		c.SetPermissionError(model.PERMISSION_READ_CLASS)
   426  		return
   427  	}
   428  
   429  	membersTimezones, err := c.App.GetClassMembersTimezones(c.Params.ClassId)
   430  	if err != nil {
   431  		c.Err = err
   432  		return
   433  	}
   434  
   435  	w.Write([]byte(model.ArrayToJson(membersTimezones)))
   436  }
   437  
   438  func getClassMembersByIds(c *Context, w http.ResponseWriter, r *http.Request) {
   439  	c.RequireClassId()
   440  	if c.Err != nil {
   441  		return
   442  	}
   443  
   444  	userIds := model.ArrayFromJson(r.Body)
   445  	if len(userIds) == 0 {
   446  		c.SetInvalidParam("user_ids")
   447  		return
   448  	}
   449  
   450  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_READ_CLASS) {
   451  		c.SetPermissionError(model.PERMISSION_READ_CLASS)
   452  		return
   453  	}
   454  
   455  	members, err := c.App.GetClassMembersByIds(c.Params.ClassId, userIds)
   456  	if err != nil {
   457  		c.Err = err
   458  		return
   459  	}
   460  
   461  	w.Write([]byte(members.ToJson()))
   462  }
   463  
   464  func getClassMember(c *Context, w http.ResponseWriter, r *http.Request) {
   465  	c.RequireClassId().RequireUserId()
   466  	if c.Err != nil {
   467  		return
   468  	}
   469  
   470  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_READ_CLASS) {
   471  		c.SetPermissionError(model.PERMISSION_READ_CLASS)
   472  		return
   473  	}
   474  
   475  	member, err := c.App.GetClassMember(c.Params.ClassId, c.Params.UserId)
   476  	if err != nil {
   477  		c.Err = err
   478  		return
   479  	}
   480  
   481  	w.Write([]byte(member.ToJson()))
   482  }
   483  
   484  func getClassMembersForUser(c *Context, w http.ResponseWriter, r *http.Request) {
   485  	c.RequireUserId().RequireBranchId()
   486  	if c.Err != nil {
   487  		return
   488  	}
   489  
   490  	if !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_VIEW_BRANCH) {
   491  		c.SetPermissionError(model.PERMISSION_VIEW_BRANCH)
   492  		return
   493  	}
   494  
   495  	if c.App.Session().UserId != c.Params.UserId && !c.App.SessionHasPermissionToBranch(*c.App.Session(), c.Params.BranchId, model.PERMISSION_MANAGE_SYSTEM) {
   496  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   497  		return
   498  	}
   499  
   500  	members, err := c.App.GetClassMembersForUser(c.Params.BranchId, c.Params.UserId)
   501  	if err != nil {
   502  		c.Err = err
   503  		return
   504  	}
   505  
   506  	w.Write([]byte(members.ToJson()))
   507  }
   508  
   509  func updateClassMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   510  	c.RequireClassId().RequireUserId()
   511  	if c.Err != nil {
   512  		return
   513  	}
   514  
   515  	props := model.MapFromJson(r.Body)
   516  
   517  	newRoles := props["roles"]
   518  	if !(model.IsValidUserRoles(newRoles)) {
   519  		c.SetInvalidParam("roles")
   520  		return
   521  	}
   522  
   523  	auditRec := c.MakeAuditRecord("updateClassMemberRoles", audit.Fail)
   524  	defer c.LogAuditRec(auditRec)
   525  	auditRec.AddMeta("class_id", c.Params.ClassId)
   526  	auditRec.AddMeta("roles", newRoles)
   527  
   528  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_MANAGE_CLASS_ROLES) {
   529  		c.SetPermissionError(model.PERMISSION_MANAGE_CLASS_ROLES)
   530  		return
   531  	}
   532  
   533  	if _, err := c.App.UpdateClassMemberRoles(c.Params.ClassId, c.Params.UserId, newRoles); err != nil {
   534  		c.Err = err
   535  		return
   536  	}
   537  
   538  	auditRec.Success()
   539  
   540  	ReturnStatusOK(w)
   541  }
   542  
   543  func updateClassMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Request) {
   544  	c.RequireClassId().RequireUserId()
   545  	if c.Err != nil {
   546  		return
   547  	}
   548  
   549  	schemeRoles := model.SchemeRolesFromJson(r.Body)
   550  	if schemeRoles == nil {
   551  		c.SetInvalidParam("scheme_roles")
   552  		return
   553  	}
   554  
   555  	auditRec := c.MakeAuditRecord("updateClassMemberSchemeRoles", audit.Fail)
   556  	defer c.LogAuditRec(auditRec)
   557  	auditRec.AddMeta("class_id", c.Params.ClassId)
   558  	auditRec.AddMeta("roles", schemeRoles)
   559  
   560  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), c.Params.ClassId, model.PERMISSION_MANAGE_CLASS_ROLES) {
   561  		c.SetPermissionError(model.PERMISSION_MANAGE_CLASS_ROLES)
   562  		return
   563  	}
   564  
   565  	if _, err := c.App.UpdateClassMemberSchemeRoles(c.Params.ClassId, c.Params.UserId, schemeRoles.SchemeUser, schemeRoles.SchemeAdmin); err != nil {
   566  		c.Err = err
   567  		return
   568  	}
   569  
   570  	auditRec.Success()
   571  
   572  	ReturnStatusOK(w)
   573  }
   574  
   575  func updateClassMemberNotifyProps(c *Context, w http.ResponseWriter, r *http.Request) {
   576  	c.RequireClassId().RequireUserId()
   577  	if c.Err != nil {
   578  		return
   579  	}
   580  
   581  	props := model.MapFromJson(r.Body)
   582  	if props == nil {
   583  		c.SetInvalidParam("notify_props")
   584  		return
   585  	}
   586  
   587  	auditRec := c.MakeAuditRecord("updateClassMemberNotifyProps", audit.Fail)
   588  	defer c.LogAuditRec(auditRec)
   589  	auditRec.AddMeta("class_id", c.Params.ClassId)
   590  	auditRec.AddMeta("props", props)
   591  
   592  	if !c.App.SessionHasPermissionToUser(*c.App.Session(), c.Params.UserId) {
   593  		c.SetPermissionError(model.PERMISSION_EDIT_OTHER_USERS)
   594  		return
   595  	}
   596  
   597  	_, err := c.App.UpdateClassMemberNotifyProps(props, c.Params.ClassId, c.Params.UserId)
   598  	if err != nil {
   599  		c.Err = err
   600  		return
   601  	}
   602  
   603  	auditRec.Success()
   604  
   605  	ReturnStatusOK(w)
   606  }
   607  
   608  func addClassMember(c *Context, w http.ResponseWriter, r *http.Request) {
   609  	c.RequireClassId()
   610  	if c.Err != nil {
   611  		return
   612  	}
   613  
   614  	props := model.StringInterfaceFromJson(r.Body)
   615  	userId, ok := props["user_id"].(string)
   616  	if !ok || len(userId) != 26 {
   617  		c.SetInvalidParam("user_id")
   618  		return
   619  	}
   620  
   621  	member := &model.ClassMember{
   622  		ClassId: c.Params.ClassId,
   623  		UserId:  userId,
   624  	}
   625  
   626  	postRootId, ok := props["post_root_id"].(string)
   627  	if ok && len(postRootId) != 0 && len(postRootId) != 26 {
   628  		c.SetInvalidParam("post_root_id")
   629  		return
   630  	}
   631  
   632  	if ok && len(postRootId) == 26 {
   633  		rootPost, err := c.App.GetSinglePost(postRootId)
   634  		if err != nil {
   635  			c.Err = err
   636  			return
   637  		}
   638  		if rootPost.ClassId != member.ClassId {
   639  			c.SetInvalidParam("post_root_id")
   640  			return
   641  		}
   642  	}
   643  
   644  	class, err := c.App.GetClass(member.ClassId)
   645  	if err != nil {
   646  		c.Err = err
   647  		return
   648  	}
   649  
   650  	auditRec := c.MakeAuditRecord("addClassMember", audit.Fail)
   651  	defer c.LogAuditRec(auditRec)
   652  	auditRec.AddMeta("class_id", class.Id)
   653  	auditRec.AddMeta("class_name", class.Name)
   654  
   655  	// isNewMembership := false
   656  	// if _, err = c.App.GetClassMember(member.ClassId, member.UserId); err != nil {
   657  	// 	if err.Id == store.MISSING_CLASS_MEMBER_ERROR {
   658  	// 		isNewMembership = true
   659  	// 	} else {
   660  	// 		c.Err = err
   661  	// 		return
   662  	// 	}
   663  	// }
   664  
   665  	// isSelfAdd := member.UserId == c.App.Session().UserId
   666  
   667  	if !c.App.SessionHasPermissionToClass(*c.App.Session(), class.Id, model.PERMISSION_MANAGE_CLASS_MEMBERS) {
   668  		c.SetPermissionError(model.PERMISSION_MANAGE_CLASS_MEMBERS)
   669  		return
   670  	}
   671  
   672  	cm, err := c.App.AddClassMember(member.UserId, class, c.App.Session().UserId, postRootId)
   673  	if err != nil {
   674  		c.Err = err
   675  		return
   676  	}
   677  
   678  	auditRec.Success()
   679  	auditRec.AddMeta("add_user_id", cm.UserId)
   680  	c.LogAudit("name=" + class.Name + " user_id=" + cm.UserId)
   681  
   682  	w.WriteHeader(http.StatusCreated)
   683  	w.Write([]byte(cm.ToJson()))
   684  }
   685  
   686  func removeClassMember(c *Context, w http.ResponseWriter, r *http.Request) {
   687  	c.RequireClassId().RequireUserId()
   688  	if c.Err != nil {
   689  		return
   690  	}
   691  
   692  	class, err := c.App.GetClass(c.Params.ClassId)
   693  	if err != nil {
   694  		c.Err = err
   695  		return
   696  	}
   697  
   698  	user, err := c.App.GetUser(c.Params.UserId)
   699  	if err != nil {
   700  		c.Err = err
   701  		return
   702  	}
   703  
   704  	auditRec := c.MakeAuditRecord("removeClassMember", audit.Fail)
   705  	defer c.LogAuditRec(auditRec)
   706  	auditRec.AddMeta("class_id", class.Id)
   707  	auditRec.AddMeta("class_name", class.Name)
   708  	auditRec.AddMeta("remove_user_id", user.Id)
   709  
   710  	if c.Params.UserId != c.App.Session().UserId {
   711  		if !c.App.SessionHasPermissionToClass(*c.App.Session(), class.Id, model.PERMISSION_MANAGE_CLASS_MEMBERS) {
   712  			c.SetPermissionError(model.PERMISSION_MANAGE_CLASS_MEMBERS)
   713  			return
   714  		}
   715  
   716  	}
   717  
   718  	if err = c.App.RemoveUserFromClass(c.Params.UserId, c.App.Session().UserId, class); err != nil {
   719  		c.Err = err
   720  		return
   721  	}
   722  
   723  	auditRec.Success()
   724  	c.LogAudit("name=" + class.Name + " user_id=" + c.Params.UserId)
   725  
   726  	ReturnStatusOK(w)
   727  }
   728  
   729  func updateClassScheme(c *Context, w http.ResponseWriter, r *http.Request) {
   730  	c.RequireClassId()
   731  	if c.Err != nil {
   732  		return
   733  	}
   734  
   735  	schemeID := model.SchemeIDFromJson(r.Body)
   736  	if schemeID == nil || len(*schemeID) != 26 {
   737  		c.SetInvalidParam("scheme_id")
   738  		return
   739  	}
   740  
   741  	auditRec := c.MakeAuditRecord("updateClassScheme", audit.Fail)
   742  	defer c.LogAuditRec(auditRec)
   743  	auditRec.AddMeta("new_scheme_id", schemeID)
   744  
   745  	if c.App.License() == nil {
   746  		c.Err = model.NewAppError("Api4.UpdateClassScheme", "api.class.update_class_scheme.license.error", nil, "", http.StatusNotImplemented)
   747  		return
   748  	}
   749  
   750  	if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
   751  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   752  		return
   753  	}
   754  
   755  	scheme, err := c.App.GetScheme(*schemeID)
   756  	if err != nil {
   757  		c.Err = err
   758  		return
   759  	}
   760  
   761  	if scheme.Scope != model.SCHEME_SCOPE_CLASS {
   762  		c.Err = model.NewAppError("Api4.UpdateClassScheme", "api.class.update_class_scheme.scheme_scope.error", nil, "", http.StatusBadRequest)
   763  		return
   764  	}
   765  
   766  	class, err := c.App.GetClass(c.Params.ClassId)
   767  	if err != nil {
   768  		c.Err = err
   769  		return
   770  	}
   771  
   772  	auditRec.AddMeta("class_id", class.Id)
   773  	auditRec.AddMeta("class_name", class.Name)
   774  	auditRec.AddMeta("old_scheme_id", class.SchemeId)
   775  
   776  	class.SchemeId = &scheme.Id
   777  
   778  	_, err = c.App.UpdateClassScheme(class)
   779  	if err != nil {
   780  		c.Err = err
   781  		return
   782  	}
   783  
   784  	auditRec.Success()
   785  
   786  	ReturnStatusOK(w)
   787  }
   788  func getClassModerations(c *Context, w http.ResponseWriter, r *http.Request) {
   789  	if c.App.License() == nil {
   790  		c.Err = model.NewAppError("Api4.GetClassModerations", "api.class.get_class_moderations.license.error", nil, "", http.StatusNotImplemented)
   791  		return
   792  	}
   793  
   794  	c.RequireClassId()
   795  	if c.Err != nil {
   796  		return
   797  	}
   798  
   799  	if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
   800  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   801  		return
   802  	}
   803  
   804  	class, err := c.App.GetClass(c.Params.ClassId)
   805  	if err != nil {
   806  		c.Err = err
   807  		return
   808  	}
   809  
   810  	classModerations, err := c.App.GetClassModerationsForClass(class)
   811  	if err != nil {
   812  		c.Err = err
   813  		return
   814  	}
   815  
   816  	b, marshalErr := json.Marshal(classModerations)
   817  	if marshalErr != nil {
   818  		c.Err = model.NewAppError("Api4.getClassModerations", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError)
   819  		return
   820  	}
   821  
   822  	w.Write(b)
   823  }
   824  
   825  func patchClassModerations(c *Context, w http.ResponseWriter, r *http.Request) {
   826  	if c.App.License() == nil {
   827  		c.Err = model.NewAppError("Api4.patchClassModerations", "api.class.patch_class_moderations.license.error", nil, "", http.StatusNotImplemented)
   828  		return
   829  	}
   830  
   831  	c.RequireClassId()
   832  	if c.Err != nil {
   833  		return
   834  	}
   835  
   836  	if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
   837  		c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
   838  		return
   839  	}
   840  
   841  	class, err := c.App.GetClass(c.Params.ClassId)
   842  	if err != nil {
   843  		c.Err = err
   844  		return
   845  	}
   846  
   847  	classModerationsPatch := model.ClassModerationsPatchFromJson(r.Body)
   848  	classModerations, err := c.App.PatchClassModerationsForClass(class, classModerationsPatch)
   849  	if err != nil {
   850  		c.Err = err
   851  		return
   852  	}
   853  
   854  	b, marshalErr := json.Marshal(classModerations)
   855  	if marshalErr != nil {
   856  		c.Err = model.NewAppError("Api4.patchClassModerations", "api.marshal_error", nil, marshalErr.Error(), http.StatusInternalServerError)
   857  		return
   858  	}
   859  
   860  	w.Write(b)
   861  }