Commit 4c1ddcff authored by Christopher Speller's avatar Christopher Speller Committed by Joram Wilander

MM-10703 Adding blank request context to plugin hooks for future use. (#9043)

* Adding blank request context to plugin hooks for future use.

* Rename RequestContext to Context

* Adding context to ServeHTTP and ExecuteCommand

* Fixing import cycle in test.
parent 7bfb5aec
......@@ -282,6 +282,7 @@ ldap-mocks: ## Creates mock files for ldap.
plugin-mocks: ## Creates mock files for plugins.
go get github.com/vektra/mockery/...
$(GOPATH)/bin/mockery -dir plugin -name API -output plugin/plugintest -outpkg plugintest -case underscore -note 'Regenerate this file using `make plugin-mocks`.'
$(GOPATH)/bin/mockery -dir plugin -name API -inpkg -output plugin -testonly -outpkg plugin -case underscore -note 'Regenerate this file using `make plugin-mocks`.'
$(GOPATH)/bin/mockery -dir plugin -name Hooks -output plugin/plugintest -outpkg plugintest -case underscore -note 'Regenerate this file using `make plugin-mocks`.'
pluginapi: ## Generates api and hooks glue code for plugins
......
......@@ -9,6 +9,7 @@ import (
"strings"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin"
)
type PluginCommand struct {
......@@ -104,7 +105,7 @@ func (a *App) ExecutePluginCommand(args *model.CommandArgs) (*model.Command, *mo
if err != nil {
return pc.Command, nil, model.NewAppError("ExecutePluginCommand", "model.plugin_command.error.app_error", nil, "err="+err.Error(), http.StatusInternalServerError)
}
response, appErr := pluginHooks.ExecuteCommand(args)
response, appErr := pluginHooks.ExecuteCommand(plugin.NewBlankContext(), args)
return pc.Command, response, appErr
}
}
......
......@@ -10,6 +10,7 @@ import (
"github.com/gorilla/mux"
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin"
)
func (a *App) ServePluginRequest(w http.ResponseWriter, r *http.Request) {
......@@ -33,7 +34,7 @@ func (a *App) ServePluginRequest(w http.ResponseWriter, r *http.Request) {
a.servePluginRequest(w, r, hooks.ServeHTTP)
}
func (a *App) servePluginRequest(w http.ResponseWriter, r *http.Request, handler http.HandlerFunc) {
func (a *App) servePluginRequest(w http.ResponseWriter, r *http.Request, handler func(*plugin.Context, http.ResponseWriter, *http.Request)) {
token := ""
authHeader := r.Header.Get(model.HEADER_AUTH)
......@@ -71,5 +72,5 @@ func (a *App) servePluginRequest(w http.ResponseWriter, r *http.Request, handler
r.URL.RawQuery = newQuery.Encode()
r.URL.Path = strings.TrimPrefix(r.URL.Path, "/plugins/"+params["plugin_id"])
handler(w, r)
handler(plugin.NewBlankContext(), w, r)
}
......@@ -10,6 +10,7 @@ import (
"github.com/gorilla/mux"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
......@@ -68,7 +69,7 @@ func TestHandlePluginRequest(t *testing.T) {
var assertions func(*http.Request)
router := mux.NewRouter()
router.HandleFunc("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}/{anything:.*}", func(_ http.ResponseWriter, r *http.Request) {
th.App.servePluginRequest(nil, r, func(_ http.ResponseWriter, r *http.Request) {
th.App.servePluginRequest(nil, r, func(_ *plugin.Context, _ http.ResponseWriter, r *http.Request) {
assertions(r)
})
})
......
......@@ -163,8 +163,9 @@ func (a *App) CreatePost(post *model.Post, channel *model.Channel, triggerWebhoo
if a.PluginsReady() {
var rejectionReason string
pluginContext := &plugin.Context{}
a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool {
post, rejectionReason = hooks.MessageWillBePosted(post)
post, rejectionReason = hooks.MessageWillBePosted(pluginContext, post)
return post != nil
}, plugin.MessageWillBePostedId)
if post == nil {
......@@ -181,8 +182,9 @@ func (a *App) CreatePost(post *model.Post, channel *model.Channel, triggerWebhoo
if a.PluginsReady() {
a.Go(func() {
pluginContext := &plugin.Context{}
a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool {
hooks.MessageHasBeenPosted(rpost)
hooks.MessageHasBeenPosted(pluginContext, rpost)
return true
}, plugin.MessageHasBeenPostedId)
})
......@@ -394,8 +396,9 @@ func (a *App) UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model
if a.PluginsReady() {
var rejectionReason string
pluginContext := &plugin.Context{}
a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool {
newPost, rejectionReason = hooks.MessageWillBeUpdated(newPost, oldPost)
newPost, rejectionReason = hooks.MessageWillBeUpdated(pluginContext, newPost, oldPost)
return post != nil
}, plugin.MessageWillBeUpdatedId)
if newPost == nil {
......@@ -410,8 +413,9 @@ func (a *App) UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model
if a.PluginsReady() {
a.Go(func() {
pluginContext := &plugin.Context{}
a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool {
hooks.MessageHasBeenUpdated(newPost, oldPost)
hooks.MessageHasBeenUpdated(pluginContext, newPost, oldPost)
return true
}, plugin.MessageHasBeenUpdatedId)
})
......
......@@ -226,10 +226,11 @@ func init() {
type ServeHTTPArgs struct {
ResponseWriterStream uint32
Request *http.Request
Context *Context
RequestBodyStream uint32
}
func (g *HooksRPCClient) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (g *HooksRPCClient) ServeHTTP(c *Context, w http.ResponseWriter, r *http.Request) {
if !g.implemented[ServeHTTPId] {
http.NotFound(w, r)
return
......@@ -282,6 +283,7 @@ func (g *HooksRPCClient) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
if err := g.client.Call("Plugin.ServeHTTP", ServeHTTPArgs{
Context: c,
ResponseWriterStream: serveHTTPStreamId,
Request: forwardedRequest,
RequestBodyStream: requestBodyStreamId,
......@@ -314,8 +316,10 @@ func (s *HooksRPCServer) ServeHTTP(args *ServeHTTPArgs, returns *struct{}) error
}
defer r.Body.Close()
if hook, ok := s.impl.(http.Handler); ok {
hook.ServeHTTP(w, r)
if hook, ok := s.impl.(interface {
ServeHTTP(c *Context, w http.ResponseWriter, r *http.Request)
}); ok {
hook.ServeHTTP(args.Context, w, r)
} else {
http.NotFound(w, r)
}
......
......@@ -84,7 +84,8 @@ func init() {
}
type ExecuteCommandArgs struct {
A *model.CommandArgs
A *Context
B *model.CommandArgs
}
type ExecuteCommandReturns struct {
......@@ -92,8 +93,8 @@ type ExecuteCommandReturns struct {
B *model.AppError
}
func (g *HooksRPCClient) ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
_args := &ExecuteCommandArgs{args}
func (g *HooksRPCClient) ExecuteCommand(c *Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
_args := &ExecuteCommandArgs{c, args}
_returns := &ExecuteCommandReturns{}
if g.implemented[ExecuteCommandId] {
if err := g.client.Call("Plugin.ExecuteCommand", _args, _returns); err != nil {
......@@ -105,9 +106,9 @@ func (g *HooksRPCClient) ExecuteCommand(args *model.CommandArgs) (*model.Command
func (s *HooksRPCServer) ExecuteCommand(args *ExecuteCommandArgs, returns *ExecuteCommandReturns) error {
if hook, ok := s.impl.(interface {
ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.AppError)
ExecuteCommand(c *Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError)
}); ok {
returns.A, returns.B = hook.ExecuteCommand(args.A)
returns.A, returns.B = hook.ExecuteCommand(args.A, args.B)
} else {
return fmt.Errorf("Hook ExecuteCommand called but not implemented.")
}
......@@ -119,7 +120,8 @@ func init() {
}
type MessageWillBePostedArgs struct {
A *model.Post
A *Context
B *model.Post
}
type MessageWillBePostedReturns struct {
......@@ -127,8 +129,8 @@ type MessageWillBePostedReturns struct {
B string
}
func (g *HooksRPCClient) MessageWillBePosted(post *model.Post) (*model.Post, string) {
_args := &MessageWillBePostedArgs{post}
func (g *HooksRPCClient) MessageWillBePosted(c *Context, post *model.Post) (*model.Post, string) {
_args := &MessageWillBePostedArgs{c, post}
_returns := &MessageWillBePostedReturns{}
if g.implemented[MessageWillBePostedId] {
if err := g.client.Call("Plugin.MessageWillBePosted", _args, _returns); err != nil {
......@@ -140,9 +142,9 @@ func (g *HooksRPCClient) MessageWillBePosted(post *model.Post) (*model.Post, str
func (s *HooksRPCServer) MessageWillBePosted(args *MessageWillBePostedArgs, returns *MessageWillBePostedReturns) error {
if hook, ok := s.impl.(interface {
MessageWillBePosted(post *model.Post) (*model.Post, string)
MessageWillBePosted(c *Context, post *model.Post) (*model.Post, string)
}); ok {
returns.A, returns.B = hook.MessageWillBePosted(args.A)
returns.A, returns.B = hook.MessageWillBePosted(args.A, args.B)
} else {
return fmt.Errorf("Hook MessageWillBePosted called but not implemented.")
}
......@@ -154,8 +156,9 @@ func init() {
}
type MessageWillBeUpdatedArgs struct {
A *model.Post
A *Context
B *model.Post
C *model.Post
}
type MessageWillBeUpdatedReturns struct {
......@@ -163,8 +166,8 @@ type MessageWillBeUpdatedReturns struct {
B string
}
func (g *HooksRPCClient) MessageWillBeUpdated(newPost, oldPost *model.Post) (*model.Post, string) {
_args := &MessageWillBeUpdatedArgs{newPost, oldPost}
func (g *HooksRPCClient) MessageWillBeUpdated(c *Context, newPost, oldPost *model.Post) (*model.Post, string) {
_args := &MessageWillBeUpdatedArgs{c, newPost, oldPost}
_returns := &MessageWillBeUpdatedReturns{}
if g.implemented[MessageWillBeUpdatedId] {
if err := g.client.Call("Plugin.MessageWillBeUpdated", _args, _returns); err != nil {
......@@ -176,9 +179,9 @@ func (g *HooksRPCClient) MessageWillBeUpdated(newPost, oldPost *model.Post) (*mo
func (s *HooksRPCServer) MessageWillBeUpdated(args *MessageWillBeUpdatedArgs, returns *MessageWillBeUpdatedReturns) error {
if hook, ok := s.impl.(interface {
MessageWillBeUpdated(newPost, oldPost *model.Post) (*model.Post, string)
MessageWillBeUpdated(c *Context, newPost, oldPost *model.Post) (*model.Post, string)
}); ok {
returns.A, returns.B = hook.MessageWillBeUpdated(args.A, args.B)
returns.A, returns.B = hook.MessageWillBeUpdated(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook MessageWillBeUpdated called but not implemented.")
}
......@@ -190,14 +193,15 @@ func init() {
}
type MessageHasBeenPostedArgs struct {
A *model.Post
A *Context
B *model.Post
}
type MessageHasBeenPostedReturns struct {
}
func (g *HooksRPCClient) MessageHasBeenPosted(post *model.Post) {
_args := &MessageHasBeenPostedArgs{post}
func (g *HooksRPCClient) MessageHasBeenPosted(c *Context, post *model.Post) {
_args := &MessageHasBeenPostedArgs{c, post}
_returns := &MessageHasBeenPostedReturns{}
if g.implemented[MessageHasBeenPostedId] {
if err := g.client.Call("Plugin.MessageHasBeenPosted", _args, _returns); err != nil {
......@@ -209,9 +213,9 @@ func (g *HooksRPCClient) MessageHasBeenPosted(post *model.Post) {
func (s *HooksRPCServer) MessageHasBeenPosted(args *MessageHasBeenPostedArgs, returns *MessageHasBeenPostedReturns) error {
if hook, ok := s.impl.(interface {
MessageHasBeenPosted(post *model.Post)
MessageHasBeenPosted(c *Context, post *model.Post)
}); ok {
hook.MessageHasBeenPosted(args.A)
hook.MessageHasBeenPosted(args.A, args.B)
} else {
return fmt.Errorf("Hook MessageHasBeenPosted called but not implemented.")
}
......@@ -223,15 +227,16 @@ func init() {
}
type MessageHasBeenUpdatedArgs struct {
A *model.Post
A *Context
B *model.Post
C *model.Post
}
type MessageHasBeenUpdatedReturns struct {
}
func (g *HooksRPCClient) MessageHasBeenUpdated(newPost, oldPost *model.Post) {
_args := &MessageHasBeenUpdatedArgs{newPost, oldPost}
func (g *HooksRPCClient) MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post) {
_args := &MessageHasBeenUpdatedArgs{c, newPost, oldPost}
_returns := &MessageHasBeenUpdatedReturns{}
if g.implemented[MessageHasBeenUpdatedId] {
if err := g.client.Call("Plugin.MessageHasBeenUpdated", _args, _returns); err != nil {
......@@ -243,9 +248,9 @@ func (g *HooksRPCClient) MessageHasBeenUpdated(newPost, oldPost *model.Post) {
func (s *HooksRPCServer) MessageHasBeenUpdated(args *MessageHasBeenUpdatedArgs, returns *MessageHasBeenUpdatedReturns) error {
if hook, ok := s.impl.(interface {
MessageHasBeenUpdated(newPost, oldPost *model.Post)
MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post)
}); ok {
hook.MessageHasBeenUpdated(args.A, args.B)
hook.MessageHasBeenUpdated(args.A, args.B, args.C)
} else {
return fmt.Errorf("Hook MessageHasBeenUpdated called but not implemented.")
}
......
......@@ -48,11 +48,11 @@ type Hooks interface {
//
// The Mattermost-User-Id header will be present if (and only if) the request is by an
// authenticated user.
ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP(c *Context, w http.ResponseWriter, r *http.Request)
// ExecuteCommand executes a command that has been previously registered via the RegisterCommand
// API.
ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.AppError)
ExecuteCommand(c *Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError)
// MessageWillBePosted is invoked when a message is posted by a user before it is commited
// to the database. If you also want to act on edited posts, see MessageWillBeUpdated.
......@@ -62,7 +62,7 @@ type Hooks interface {
//
// Note that this method will be called for posts created by plugins, including the plugin that
// created the post.
MessageWillBePosted(post *model.Post) (*model.Post, string)
MessageWillBePosted(c *Context, post *model.Post) (*model.Post, string)
// MessageWillBeUpdated is invoked when a message is updated by a user before it is commited
// to the database. If you also want to act on new posts, see MessageWillBePosted.
......@@ -73,17 +73,17 @@ type Hooks interface {
//
// Note that this method will be called for posts updated by plugins, including the plugin that
// updated the post.
MessageWillBeUpdated(newPost, oldPost *model.Post) (*model.Post, string)
MessageWillBeUpdated(c *Context, newPost, oldPost *model.Post) (*model.Post, string)
// MessageHasBeenPosted is invoked after the message has been commited to the databse.
// If you need to modify or reject the post, see MessageWillBePosted
// Note that this method will be called for posts created by plugins, including the plugin that
// created the post.
MessageHasBeenPosted(post *model.Post)
MessageHasBeenPosted(c *Context, post *model.Post)
// MessageHasBeenUpdated is invoked after a message is updated and has been updated in the databse.
// If you need to modify or reject the post, see MessageWillBeUpdated
// Note that this method will be called for posts created by plugins, including the plugin that
// created the post.
MessageHasBeenUpdated(newPost, oldPost *model.Post)
MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post)
}
This diff is collapsed.
......@@ -7,19 +7,20 @@ package plugintest
import http "net/http"
import mock "github.com/stretchr/testify/mock"
import model "github.com/mattermost/mattermost-server/model"
import plugin "github.com/mattermost/mattermost-server/plugin"
// Hooks is an autogenerated mock type for the Hooks type
type Hooks struct {
mock.Mock
}
// ExecuteCommand provides a mock function with given fields: args
func (_m *Hooks) ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
ret := _m.Called(args)
// ExecuteCommand provides a mock function with given fields: c, args
func (_m *Hooks) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
ret := _m.Called(c, args)
var r0 *model.CommandResponse
if rf, ok := ret.Get(0).(func(*model.CommandArgs) *model.CommandResponse); ok {
r0 = rf(args)
if rf, ok := ret.Get(0).(func(*plugin.Context, *model.CommandArgs) *model.CommandResponse); ok {
r0 = rf(c, args)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.CommandResponse)
......@@ -27,8 +28,8 @@ func (_m *Hooks) ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(*model.CommandArgs) *model.AppError); ok {
r1 = rf(args)
if rf, ok := ret.Get(1).(func(*plugin.Context, *model.CommandArgs) *model.AppError); ok {
r1 = rf(c, args)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
......@@ -61,23 +62,23 @@ func (_m *Hooks) Implemented() ([]string, error) {
return r0, r1
}
// MessageHasBeenPosted provides a mock function with given fields: post
func (_m *Hooks) MessageHasBeenPosted(post *model.Post) {
_m.Called(post)
// MessageHasBeenPosted provides a mock function with given fields: c, post
func (_m *Hooks) MessageHasBeenPosted(c *plugin.Context, post *model.Post) {
_m.Called(c, post)
}
// MessageHasBeenUpdated provides a mock function with given fields: newPost, oldPost
func (_m *Hooks) MessageHasBeenUpdated(newPost *model.Post, oldPost *model.Post) {
_m.Called(newPost, oldPost)
// MessageHasBeenUpdated provides a mock function with given fields: c, newPost, oldPost
func (_m *Hooks) MessageHasBeenUpdated(c *plugin.Context, newPost *model.Post, oldPost *model.Post) {
_m.Called(c, newPost, oldPost)
}
// MessageWillBePosted provides a mock function with given fields: post
func (_m *Hooks) MessageWillBePosted(post *model.Post) (*model.Post, string) {
ret := _m.Called(post)
// MessageWillBePosted provides a mock function with given fields: c, post
func (_m *Hooks) MessageWillBePosted(c *plugin.Context, post *model.Post) (*model.Post, string) {
ret := _m.Called(c, post)
var r0 *model.Post
if rf, ok := ret.Get(0).(func(*model.Post) *model.Post); ok {
r0 = rf(post)
if rf, ok := ret.Get(0).(func(*plugin.Context, *model.Post) *model.Post); ok {
r0 = rf(c, post)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Post)
......@@ -85,8 +86,8 @@ func (_m *Hooks) MessageWillBePosted(post *model.Post) (*model.Post, string) {
}
var r1 string
if rf, ok := ret.Get(1).(func(*model.Post) string); ok {
r1 = rf(post)
if rf, ok := ret.Get(1).(func(*plugin.Context, *model.Post) string); ok {
r1 = rf(c, post)
} else {
r1 = ret.Get(1).(string)
}
......@@ -94,13 +95,13 @@ func (_m *Hooks) MessageWillBePosted(post *model.Post) (*model.Post, string) {
return r0, r1
}
// MessageWillBeUpdated provides a mock function with given fields: newPost, oldPost
func (_m *Hooks) MessageWillBeUpdated(newPost *model.Post, oldPost *model.Post) (*model.Post, string) {
ret := _m.Called(newPost, oldPost)
// MessageWillBeUpdated provides a mock function with given fields: c, newPost, oldPost
func (_m *Hooks) MessageWillBeUpdated(c *plugin.Context, newPost *model.Post, oldPost *model.Post) (*model.Post, string) {
ret := _m.Called(c, newPost, oldPost)
var r0 *model.Post
if rf, ok := ret.Get(0).(func(*model.Post, *model.Post) *model.Post); ok {
r0 = rf(newPost, oldPost)
if rf, ok := ret.Get(0).(func(*plugin.Context, *model.Post, *model.Post) *model.Post); ok {
r0 = rf(c, newPost, oldPost)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Post)
......@@ -108,8 +109,8 @@ func (_m *Hooks) MessageWillBeUpdated(newPost *model.Post, oldPost *model.Post)
}
var r1 string
if rf, ok := ret.Get(1).(func(*model.Post, *model.Post) string); ok {
r1 = rf(newPost, oldPost)
if rf, ok := ret.Get(1).(func(*plugin.Context, *model.Post, *model.Post) string); ok {
r1 = rf(c, newPost, oldPost)
} else {
r1 = ret.Get(1).(string)
}
......@@ -159,7 +160,7 @@ func (_m *Hooks) OnDeactivate() error {
return r0
}
// ServeHTTP provides a mock function with given fields: w, r
func (_m *Hooks) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_m.Called(w, r)
// ServeHTTP provides a mock function with given fields: c, w, r
func (_m *Hooks) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
_m.Called(c, w, r)
}
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package plugin
type Context struct {
}
func NewBlankContext() *Context {
return &Context{}
}
......@@ -12,7 +12,6 @@ import (
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin/plugintest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
......@@ -66,7 +65,7 @@ func testSupervisor(t *testing.T) {
ioutil.WriteFile(filepath.Join(dir, "plugin.json"), []byte(`{"id": "foo", "backend": {"executable": "backend.exe"}}`), 0600)
bundle := model.BundleInfoForPath(dir)
var api plugintest.API
var api MockAPI
api.On("LoadPluginConfiguration", mock.Anything).Return(nil)
log := mlog.NewLogger(&mlog.LoggerConfiguration{
EnableConsole: true,
......
......@@ -14,6 +14,7 @@ import (
"github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/mlog"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin"
"github.com/mattermost/mattermost-server/utils"
)
......@@ -526,3 +527,11 @@ func (c *Context) RequireRoleName() *Context {
return c
}
func (c *Context) ToPluginContext() *plugin.Context {
return &plugin.Context{
//sessionId: c.Session.Id,
//requestId: c.RequestId,
//userIp: c.IpAddress,
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment