github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+incompatible/api4/webhook.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"net/http"
     8  
     9  	"github.com/mattermost/mattermost-server/model"
    10  )
    11  
    12  func (api *API) InitWebhook() {
    13  	api.BaseRoutes.IncomingHooks.Handle("", api.ApiSessionRequired(createIncomingHook)).Methods("POST")
    14  	api.BaseRoutes.IncomingHooks.Handle("", api.ApiSessionRequired(getIncomingHooks)).Methods("GET")
    15  	api.BaseRoutes.IncomingHook.Handle("", api.ApiSessionRequired(getIncomingHook)).Methods("GET")
    16  	api.BaseRoutes.IncomingHook.Handle("", api.ApiSessionRequired(updateIncomingHook)).Methods("PUT")
    17  	api.BaseRoutes.IncomingHook.Handle("", api.ApiSessionRequired(deleteIncomingHook)).Methods("DELETE")
    18  
    19  	api.BaseRoutes.OutgoingHooks.Handle("", api.ApiSessionRequired(createOutgoingHook)).Methods("POST")
    20  	api.BaseRoutes.OutgoingHooks.Handle("", api.ApiSessionRequired(getOutgoingHooks)).Methods("GET")
    21  	api.BaseRoutes.OutgoingHook.Handle("", api.ApiSessionRequired(getOutgoingHook)).Methods("GET")
    22  	api.BaseRoutes.OutgoingHook.Handle("", api.ApiSessionRequired(updateOutgoingHook)).Methods("PUT")
    23  	api.BaseRoutes.OutgoingHook.Handle("", api.ApiSessionRequired(deleteOutgoingHook)).Methods("DELETE")
    24  	api.BaseRoutes.OutgoingHook.Handle("/regen_token", api.ApiSessionRequired(regenOutgoingHookToken)).Methods("POST")
    25  }
    26  
    27  func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
    28  	hook := model.IncomingWebhookFromJson(r.Body)
    29  	if hook == nil {
    30  		c.SetInvalidParam("incoming_webhook")
    31  		return
    32  	}
    33  
    34  	channel, err := c.App.GetChannel(hook.ChannelId)
    35  	if err != nil {
    36  		c.Err = err
    37  		return
    38  	}
    39  
    40  	c.LogAudit("attempt")
    41  
    42  	if !c.App.SessionHasPermissionToTeam(c.Session, channel.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
    43  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
    44  		return
    45  	}
    46  
    47  	if channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
    48  		c.LogAudit("fail - bad channel permissions")
    49  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
    50  		return
    51  	}
    52  
    53  	incomingHook, err := c.App.CreateIncomingWebhookForChannel(c.Session.UserId, channel, hook)
    54  	if err != nil {
    55  		c.Err = err
    56  		return
    57  	}
    58  
    59  	c.LogAudit("success")
    60  	w.WriteHeader(http.StatusCreated)
    61  	w.Write([]byte(incomingHook.ToJson()))
    62  }
    63  
    64  func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
    65  	c.RequireHookId()
    66  	if c.Err != nil {
    67  		return
    68  	}
    69  
    70  	updatedHook := model.IncomingWebhookFromJson(r.Body)
    71  	if updatedHook == nil {
    72  		c.SetInvalidParam("incoming_webhook")
    73  		return
    74  	}
    75  
    76  	// The hook being updated in the payload must be the same one as indicated in the URL.
    77  	if updatedHook.Id != c.Params.HookId {
    78  		c.SetInvalidParam("hook_id")
    79  		return
    80  	}
    81  
    82  	c.LogAudit("attempt")
    83  
    84  	oldHook, err := c.App.GetIncomingWebhook(c.Params.HookId)
    85  	if err != nil {
    86  		c.Err = err
    87  		return
    88  	}
    89  
    90  	if updatedHook.TeamId == "" {
    91  		updatedHook.TeamId = oldHook.TeamId
    92  	}
    93  
    94  	if updatedHook.TeamId != oldHook.TeamId {
    95  		c.Err = model.NewAppError("updateIncomingHook", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest)
    96  		return
    97  	}
    98  
    99  	if !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   100  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   101  		return
   102  	}
   103  
   104  	if c.Session.UserId != oldHook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
   105  		c.LogAudit("fail - inappropriate permissions")
   106  		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
   107  		return
   108  	}
   109  
   110  	channel, err := c.App.GetChannel(updatedHook.ChannelId)
   111  	if err != nil {
   112  		c.Err = err
   113  		return
   114  	}
   115  
   116  	if channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_READ_CHANNEL) {
   117  		c.LogAudit("fail - bad channel permissions")
   118  		c.SetPermissionError(model.PERMISSION_READ_CHANNEL)
   119  		return
   120  	}
   121  
   122  	incomingHook, err := c.App.UpdateIncomingWebhook(oldHook, updatedHook)
   123  	if err != nil {
   124  		c.Err = err
   125  		return
   126  	}
   127  
   128  	c.LogAudit("success")
   129  	w.WriteHeader(http.StatusCreated)
   130  	w.Write([]byte(incomingHook.ToJson()))
   131  }
   132  
   133  func getIncomingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
   134  	teamId := r.URL.Query().Get("team_id")
   135  
   136  	var hooks []*model.IncomingWebhook
   137  	var err *model.AppError
   138  
   139  	if len(teamId) > 0 {
   140  		if !c.App.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   141  			c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   142  			return
   143  		}
   144  
   145  		hooks, err = c.App.GetIncomingWebhooksForTeamPage(teamId, c.Params.Page, c.Params.PerPage)
   146  	} else {
   147  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_WEBHOOKS) {
   148  			c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   149  			return
   150  		}
   151  
   152  		hooks, err = c.App.GetIncomingWebhooksPage(c.Params.Page, c.Params.PerPage)
   153  	}
   154  
   155  	if err != nil {
   156  		c.Err = err
   157  		return
   158  	}
   159  
   160  	w.Write([]byte(model.IncomingWebhookListToJson(hooks)))
   161  }
   162  
   163  func getIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
   164  	c.RequireHookId()
   165  	if c.Err != nil {
   166  		return
   167  	}
   168  
   169  	hookId := c.Params.HookId
   170  
   171  	var err *model.AppError
   172  	var hook *model.IncomingWebhook
   173  	var channel *model.Channel
   174  
   175  	hook, err = c.App.GetIncomingWebhook(hookId)
   176  	if err != nil {
   177  		c.Err = err
   178  		return
   179  	}
   180  
   181  	channel, err = c.App.GetChannel(hook.ChannelId)
   182  	if err != nil {
   183  		c.Err = err
   184  		return
   185  	}
   186  
   187  	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) ||
   188  		(channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, hook.ChannelId, model.PERMISSION_READ_CHANNEL)) {
   189  		c.LogAudit("fail - bad permissions")
   190  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   191  		return
   192  	}
   193  
   194  	if c.Session.UserId != hook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
   195  		c.LogAudit("fail - inappropriate permissions")
   196  		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
   197  		return
   198  	}
   199  
   200  	w.Write([]byte(hook.ToJson()))
   201  }
   202  
   203  func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) {
   204  	c.RequireHookId()
   205  	if c.Err != nil {
   206  		return
   207  	}
   208  
   209  	hookId := c.Params.HookId
   210  
   211  	var err *model.AppError
   212  	var hook *model.IncomingWebhook
   213  	var channel *model.Channel
   214  
   215  	hook, err = c.App.GetIncomingWebhook(hookId)
   216  	if err != nil {
   217  		c.Err = err
   218  		return
   219  	}
   220  
   221  	channel, err = c.App.GetChannel(hook.ChannelId)
   222  	if err != nil {
   223  		c.Err = err
   224  		return
   225  	}
   226  
   227  	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) ||
   228  		(channel.Type != model.CHANNEL_OPEN && !c.App.SessionHasPermissionToChannel(c.Session, hook.ChannelId, model.PERMISSION_READ_CHANNEL)) {
   229  		c.LogAudit("fail - bad permissions")
   230  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   231  		return
   232  	}
   233  
   234  	if c.Session.UserId != hook.UserId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
   235  		c.LogAudit("fail - inappropriate permissions")
   236  		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
   237  		return
   238  	}
   239  
   240  	if err = c.App.DeleteIncomingWebhook(hookId); err != nil {
   241  		c.Err = err
   242  		return
   243  	}
   244  
   245  	ReturnStatusOK(w)
   246  }
   247  
   248  func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
   249  	c.RequireHookId()
   250  	if c.Err != nil {
   251  		return
   252  	}
   253  
   254  	updatedHook := model.OutgoingWebhookFromJson(r.Body)
   255  	if updatedHook == nil {
   256  		c.SetInvalidParam("outgoing_webhook")
   257  		return
   258  	}
   259  
   260  	// The hook being updated in the payload must be the same one as indicated in the URL.
   261  	if updatedHook.Id != c.Params.HookId {
   262  		c.SetInvalidParam("hook_id")
   263  		return
   264  	}
   265  
   266  	c.LogAudit("attempt")
   267  
   268  	oldHook, err := c.App.GetOutgoingWebhook(c.Params.HookId)
   269  	if err != nil {
   270  		c.Err = err
   271  		return
   272  	}
   273  
   274  	if updatedHook.TeamId == "" {
   275  		updatedHook.TeamId = oldHook.TeamId
   276  	}
   277  
   278  	if updatedHook.TeamId != oldHook.TeamId {
   279  		c.Err = model.NewAppError("updateOutgoingHook", "api.webhook.team_mismatch.app_error", nil, "user_id="+c.Session.UserId, http.StatusBadRequest)
   280  		return
   281  	}
   282  
   283  	if !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   284  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   285  		return
   286  	}
   287  
   288  	if c.Session.UserId != oldHook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, updatedHook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
   289  		c.LogAudit("fail - inappropriate permissions")
   290  		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
   291  		return
   292  	}
   293  
   294  	updatedHook.CreatorId = c.Session.UserId
   295  
   296  	rhook, err := c.App.UpdateOutgoingWebhook(oldHook, updatedHook)
   297  	if err != nil {
   298  		c.Err = err
   299  		return
   300  	}
   301  
   302  	c.LogAudit("success")
   303  	w.Write([]byte(rhook.ToJson()))
   304  }
   305  
   306  func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
   307  	hook := model.OutgoingWebhookFromJson(r.Body)
   308  	if hook == nil {
   309  		c.SetInvalidParam("outgoing_webhook")
   310  		return
   311  	}
   312  
   313  	c.LogAudit("attempt")
   314  
   315  	hook.CreatorId = c.Session.UserId
   316  
   317  	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   318  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   319  		return
   320  	}
   321  
   322  	rhook, err := c.App.CreateOutgoingWebhook(hook)
   323  	if err != nil {
   324  		c.LogAudit("fail")
   325  		c.Err = err
   326  		return
   327  	}
   328  
   329  	c.LogAudit("success")
   330  	w.WriteHeader(http.StatusCreated)
   331  	w.Write([]byte(rhook.ToJson()))
   332  }
   333  
   334  func getOutgoingHooks(c *Context, w http.ResponseWriter, r *http.Request) {
   335  	channelId := r.URL.Query().Get("channel_id")
   336  	teamId := r.URL.Query().Get("team_id")
   337  
   338  	var hooks []*model.OutgoingWebhook
   339  	var err *model.AppError
   340  
   341  	if len(channelId) > 0 {
   342  		if !c.App.SessionHasPermissionToChannel(c.Session, channelId, model.PERMISSION_MANAGE_WEBHOOKS) {
   343  			c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   344  			return
   345  		}
   346  
   347  		hooks, err = c.App.GetOutgoingWebhooksForChannelPage(channelId, c.Params.Page, c.Params.PerPage)
   348  	} else if len(teamId) > 0 {
   349  		if !c.App.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   350  			c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   351  			return
   352  		}
   353  
   354  		hooks, err = c.App.GetOutgoingWebhooksForTeamPage(teamId, c.Params.Page, c.Params.PerPage)
   355  	} else {
   356  		if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_WEBHOOKS) {
   357  			c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   358  			return
   359  		}
   360  
   361  		hooks, err = c.App.GetOutgoingWebhooksPage(c.Params.Page, c.Params.PerPage)
   362  	}
   363  
   364  	if err != nil {
   365  		c.Err = err
   366  		return
   367  	}
   368  
   369  	w.Write([]byte(model.OutgoingWebhookListToJson(hooks)))
   370  }
   371  
   372  func getOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
   373  	c.RequireHookId()
   374  	if c.Err != nil {
   375  		return
   376  	}
   377  
   378  	hook, err := c.App.GetOutgoingWebhook(c.Params.HookId)
   379  	if err != nil {
   380  		c.Err = err
   381  		return
   382  	}
   383  
   384  	c.LogAudit("attempt")
   385  
   386  	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   387  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   388  		return
   389  	}
   390  
   391  	if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
   392  		c.LogAudit("fail - inappropriate permissions")
   393  		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
   394  		return
   395  	}
   396  
   397  	c.LogAudit("success")
   398  	w.Write([]byte(hook.ToJson()))
   399  }
   400  
   401  func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request) {
   402  	c.RequireHookId()
   403  	if c.Err != nil {
   404  		return
   405  	}
   406  
   407  	hook, err := c.App.GetOutgoingWebhook(c.Params.HookId)
   408  	if err != nil {
   409  		c.Err = err
   410  		return
   411  	}
   412  
   413  	c.LogAudit("attempt")
   414  
   415  	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   416  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   417  		return
   418  	}
   419  
   420  	if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
   421  		c.LogAudit("fail - inappropriate permissions")
   422  		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
   423  		return
   424  	}
   425  
   426  	rhook, err := c.App.RegenOutgoingWebhookToken(hook)
   427  	if err != nil {
   428  		c.Err = err
   429  		return
   430  	}
   431  
   432  	w.Write([]byte(rhook.ToJson()))
   433  }
   434  
   435  func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) {
   436  	c.RequireHookId()
   437  	if c.Err != nil {
   438  		return
   439  	}
   440  
   441  	hook, err := c.App.GetOutgoingWebhook(c.Params.HookId)
   442  	if err != nil {
   443  		c.Err = err
   444  		return
   445  	}
   446  
   447  	c.LogAudit("attempt")
   448  
   449  	if !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_WEBHOOKS) {
   450  		c.SetPermissionError(model.PERMISSION_MANAGE_WEBHOOKS)
   451  		return
   452  	}
   453  
   454  	if c.Session.UserId != hook.CreatorId && !c.App.SessionHasPermissionToTeam(c.Session, hook.TeamId, model.PERMISSION_MANAGE_OTHERS_WEBHOOKS) {
   455  		c.LogAudit("fail - inappropriate permissions")
   456  		c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_WEBHOOKS)
   457  		return
   458  	}
   459  
   460  	if err := c.App.DeleteOutgoingWebhook(hook.Id); err != nil {
   461  		c.LogAudit("fail")
   462  		c.Err = err
   463  		return
   464  	}
   465  
   466  	c.LogAudit("success")
   467  	ReturnStatusOK(w)
   468  }