From 54b0ef574b5dd700442fa49e57e81159d851840f Mon Sep 17 00:00:00 2001 From: Ben Schumacher Date: Wed, 14 Jul 2021 15:08:22 +0200 Subject: [PATCH] [MM-36664] Added plugin API methods for user access tokens and OAuth apps (#17832) --- app/plugin_api.go | 34 ++++++ plugin/api.go | 34 ++++++ plugin/api_timer_layer_generated.go | 42 +++++++ plugin/client_rpc_generated.go | 172 ++++++++++++++++++++++++++++ plugin/plugintest/api.go | 132 +++++++++++++++++++++ 5 files changed, 414 insertions(+) diff --git a/app/plugin_api.go b/app/plugin_api.go index 294eccfdb2..757d5f1725 100644 --- a/app/plugin_api.go +++ b/app/plugin_api.go @@ -284,6 +284,19 @@ func (api *PluginAPI) DeletePreferencesForUser(userID string, preferences []mode return api.app.DeletePreferences(userID, preferences) } +func (api *PluginAPI) CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) { + return api.app.CreateUserAccessToken(token) +} + +func (api *PluginAPI) RevokeUserAccessToken(tokenID string) *model.AppError { + accessToken, err := api.app.GetUserAccessToken(tokenID, false) + if err != nil { + return err + } + + return api.app.RevokeUserAccessToken(accessToken) +} + func (api *PluginAPI) UpdateUser(user *model.User) (*model.User, *model.AppError) { return api.app.UpdateUser(user, true) } @@ -1089,6 +1102,27 @@ func (api *PluginAPI) DeleteCommand(commandID string) error { return nil } +func (api *PluginAPI) CreateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + return api.app.CreateOAuthApp(app) +} + +func (api *PluginAPI) GetOAuthApp(appID string) (*model.OAuthApp, *model.AppError) { + return api.app.GetOAuthApp(appID) +} + +func (api *PluginAPI) UpdateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + oldApp, err := api.GetOAuthApp(app.Id) + if err != nil { + return nil, err + } + + return api.app.UpdateOauthApp(oldApp, app) +} + +func (api *PluginAPI) DeleteOAuthApp(appID string) *model.AppError { + return api.app.DeleteOAuthApp(appID) +} + // PublishPluginClusterEvent broadcasts a plugin event to all other running instances of // the calling plugin. func (api *PluginAPI) PublishPluginClusterEvent(ev model.PluginClusterEvent, diff --git a/plugin/api.go b/plugin/api.go index 1f48a944ec..d2a8df21c0 100644 --- a/plugin/api.go +++ b/plugin/api.go @@ -186,6 +186,16 @@ type API interface { // Minimum server version: 5.26 DeletePreferencesForUser(userID string, preferences []model.Preference) *model.AppError + // CreateUserAccessToken creates a new access token. + // @tag User + // Minimum server version: 5.38 + CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) + + // RevokeUserAccessToken revokes an existing access token. + // @tag User + // Minimum server version: 5.38 + RevokeUserAccessToken(tokenID string) *model.AppError + // GetTeamIcon gets the team icon. // // @tag Team @@ -1075,6 +1085,30 @@ type API interface { // Minimum server version: 5.28 DeleteCommand(commandID string) error + // CreateOAuthApp creates a new OAuth App. + // + // @tag OAuth + // Minimum server version: 5.38 + CreateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) + + // GetOAuthApp gets an existing OAuth App by id. + // + // @tag OAuth + // Minimum server version: 5.38 + GetOAuthApp(appID string) (*model.OAuthApp, *model.AppError) + + // UpdateOAuthApp updates an existing OAuth App. + // + // @tag OAuth + // Minimum server version: 5.38 + UpdateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) + + // DeleteOAuthApp deletes an existing OAuth App by id. + // + // @tag OAuth + // Minimum server version: 5.38 + DeleteOAuthApp(appID string) *model.AppError + // PublishPluginClusterEvent broadcasts a plugin event to all other running instances of // the calling plugin that are present in the cluster. // diff --git a/plugin/api_timer_layer_generated.go b/plugin/api_timer_layer_generated.go index c147d2ae3a..2c3769792f 100644 --- a/plugin/api_timer_layer_generated.go +++ b/plugin/api_timer_layer_generated.go @@ -217,6 +217,20 @@ func (api *apiTimerLayer) DeletePreferencesForUser(userID string, preferences [] return _returnsA } +func (api *apiTimerLayer) CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) { + startTime := timePkg.Now() + _returnsA, _returnsB := api.apiImpl.CreateUserAccessToken(token) + api.recordTime(startTime, "CreateUserAccessToken", _returnsB == nil) + return _returnsA, _returnsB +} + +func (api *apiTimerLayer) RevokeUserAccessToken(tokenID string) *model.AppError { + startTime := timePkg.Now() + _returnsA := api.apiImpl.RevokeUserAccessToken(tokenID) + api.recordTime(startTime, "RevokeUserAccessToken", _returnsA == nil) + return _returnsA +} + func (api *apiTimerLayer) GetTeamIcon(teamID string) ([]byte, *model.AppError) { startTime := timePkg.Now() _returnsA, _returnsB := api.apiImpl.GetTeamIcon(teamID) @@ -1142,6 +1156,34 @@ func (api *apiTimerLayer) DeleteCommand(commandID string) error { return _returnsA } +func (api *apiTimerLayer) CreateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + startTime := timePkg.Now() + _returnsA, _returnsB := api.apiImpl.CreateOAuthApp(app) + api.recordTime(startTime, "CreateOAuthApp", _returnsB == nil) + return _returnsA, _returnsB +} + +func (api *apiTimerLayer) GetOAuthApp(appID string) (*model.OAuthApp, *model.AppError) { + startTime := timePkg.Now() + _returnsA, _returnsB := api.apiImpl.GetOAuthApp(appID) + api.recordTime(startTime, "GetOAuthApp", _returnsB == nil) + return _returnsA, _returnsB +} + +func (api *apiTimerLayer) UpdateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + startTime := timePkg.Now() + _returnsA, _returnsB := api.apiImpl.UpdateOAuthApp(app) + api.recordTime(startTime, "UpdateOAuthApp", _returnsB == nil) + return _returnsA, _returnsB +} + +func (api *apiTimerLayer) DeleteOAuthApp(appID string) *model.AppError { + startTime := timePkg.Now() + _returnsA := api.apiImpl.DeleteOAuthApp(appID) + api.recordTime(startTime, "DeleteOAuthApp", _returnsA == nil) + return _returnsA +} + func (api *apiTimerLayer) PublishPluginClusterEvent(ev model.PluginClusterEvent, opts model.PluginClusterEventSendOptions) error { startTime := timePkg.Now() _returnsA := api.apiImpl.PublishPluginClusterEvent(ev, opts) diff --git a/plugin/client_rpc_generated.go b/plugin/client_rpc_generated.go index 252d2fe470..309a6bfee6 100644 --- a/plugin/client_rpc_generated.go +++ b/plugin/client_rpc_generated.go @@ -1306,6 +1306,63 @@ func (s *apiRPCServer) DeletePreferencesForUser(args *Z_DeletePreferencesForUser return nil } +type Z_CreateUserAccessTokenArgs struct { + A *model.UserAccessToken +} + +type Z_CreateUserAccessTokenReturns struct { + A *model.UserAccessToken + B *model.AppError +} + +func (g *apiRPCClient) CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) { + _args := &Z_CreateUserAccessTokenArgs{token} + _returns := &Z_CreateUserAccessTokenReturns{} + if err := g.client.Call("Plugin.CreateUserAccessToken", _args, _returns); err != nil { + log.Printf("RPC call to CreateUserAccessToken API failed: %s", err.Error()) + } + return _returns.A, _returns.B +} + +func (s *apiRPCServer) CreateUserAccessToken(args *Z_CreateUserAccessTokenArgs, returns *Z_CreateUserAccessTokenReturns) error { + if hook, ok := s.impl.(interface { + CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) + }); ok { + returns.A, returns.B = hook.CreateUserAccessToken(args.A) + } else { + return encodableError(fmt.Errorf("API CreateUserAccessToken called but not implemented.")) + } + return nil +} + +type Z_RevokeUserAccessTokenArgs struct { + A string +} + +type Z_RevokeUserAccessTokenReturns struct { + A *model.AppError +} + +func (g *apiRPCClient) RevokeUserAccessToken(tokenID string) *model.AppError { + _args := &Z_RevokeUserAccessTokenArgs{tokenID} + _returns := &Z_RevokeUserAccessTokenReturns{} + if err := g.client.Call("Plugin.RevokeUserAccessToken", _args, _returns); err != nil { + log.Printf("RPC call to RevokeUserAccessToken API failed: %s", err.Error()) + } + return _returns.A +} + +func (s *apiRPCServer) RevokeUserAccessToken(args *Z_RevokeUserAccessTokenArgs, returns *Z_RevokeUserAccessTokenReturns) error { + if hook, ok := s.impl.(interface { + RevokeUserAccessToken(tokenID string) *model.AppError + }); ok { + returns.A = hook.RevokeUserAccessToken(args.A) + } else { + return encodableError(fmt.Errorf("API RevokeUserAccessToken called but not implemented.")) + } + return nil +} + type Z_GetTeamIconArgs struct { A string } @@ -5063,6 +5120,121 @@ func (s *apiRPCServer) DeleteCommand(args *Z_DeleteCommandArgs, returns *Z_Delet return nil } +type Z_CreateOAuthAppArgs struct { + A *model.OAuthApp +} + +type Z_CreateOAuthAppReturns struct { + A *model.OAuthApp + B *model.AppError +} + +func (g *apiRPCClient) CreateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + _args := &Z_CreateOAuthAppArgs{app} + _returns := &Z_CreateOAuthAppReturns{} + if err := g.client.Call("Plugin.CreateOAuthApp", _args, _returns); err != nil { + log.Printf("RPC call to CreateOAuthApp API failed: %s", err.Error()) + } + return _returns.A, _returns.B +} + +func (s *apiRPCServer) CreateOAuthApp(args *Z_CreateOAuthAppArgs, returns *Z_CreateOAuthAppReturns) error { + if hook, ok := s.impl.(interface { + CreateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) + }); ok { + returns.A, returns.B = hook.CreateOAuthApp(args.A) + } else { + return encodableError(fmt.Errorf("API CreateOAuthApp called but not implemented.")) + } + return nil +} + +type Z_GetOAuthAppArgs struct { + A string +} + +type Z_GetOAuthAppReturns struct { + A *model.OAuthApp + B *model.AppError +} + +func (g *apiRPCClient) GetOAuthApp(appID string) (*model.OAuthApp, *model.AppError) { + _args := &Z_GetOAuthAppArgs{appID} + _returns := &Z_GetOAuthAppReturns{} + if err := g.client.Call("Plugin.GetOAuthApp", _args, _returns); err != nil { + log.Printf("RPC call to GetOAuthApp API failed: %s", err.Error()) + } + return _returns.A, _returns.B +} + +func (s *apiRPCServer) GetOAuthApp(args *Z_GetOAuthAppArgs, returns *Z_GetOAuthAppReturns) error { + if hook, ok := s.impl.(interface { + GetOAuthApp(appID string) (*model.OAuthApp, *model.AppError) + }); ok { + returns.A, returns.B = hook.GetOAuthApp(args.A) + } else { + return encodableError(fmt.Errorf("API GetOAuthApp called but not implemented.")) + } + return nil +} + +type Z_UpdateOAuthAppArgs struct { + A *model.OAuthApp +} + +type Z_UpdateOAuthAppReturns struct { + A *model.OAuthApp + B *model.AppError +} + +func (g *apiRPCClient) UpdateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + _args := &Z_UpdateOAuthAppArgs{app} + _returns := &Z_UpdateOAuthAppReturns{} + if err := g.client.Call("Plugin.UpdateOAuthApp", _args, _returns); err != nil { + log.Printf("RPC call to UpdateOAuthApp API failed: %s", err.Error()) + } + return _returns.A, _returns.B +} + +func (s *apiRPCServer) UpdateOAuthApp(args *Z_UpdateOAuthAppArgs, returns *Z_UpdateOAuthAppReturns) error { + if hook, ok := s.impl.(interface { + UpdateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) + }); ok { + returns.A, returns.B = hook.UpdateOAuthApp(args.A) + } else { + return encodableError(fmt.Errorf("API UpdateOAuthApp called but not implemented.")) + } + return nil +} + +type Z_DeleteOAuthAppArgs struct { + A string +} + +type Z_DeleteOAuthAppReturns struct { + A *model.AppError +} + +func (g *apiRPCClient) DeleteOAuthApp(appID string) *model.AppError { + _args := &Z_DeleteOAuthAppArgs{appID} + _returns := &Z_DeleteOAuthAppReturns{} + if err := g.client.Call("Plugin.DeleteOAuthApp", _args, _returns); err != nil { + log.Printf("RPC call to DeleteOAuthApp API failed: %s", err.Error()) + } + return _returns.A +} + +func (s *apiRPCServer) DeleteOAuthApp(args *Z_DeleteOAuthAppArgs, returns *Z_DeleteOAuthAppReturns) error { + if hook, ok := s.impl.(interface { + DeleteOAuthApp(appID string) *model.AppError + }); ok { + returns.A = hook.DeleteOAuthApp(args.A) + } else { + return encodableError(fmt.Errorf("API DeleteOAuthApp called but not implemented.")) + } + return nil +} + type Z_PublishPluginClusterEventArgs struct { A model.PluginClusterEvent B model.PluginClusterEventSendOptions diff --git a/plugin/plugintest/api.go b/plugin/plugintest/api.go index ca9f3ce777..d75d839092 100644 --- a/plugin/plugintest/api.go +++ b/plugin/plugintest/api.go @@ -216,6 +216,31 @@ func (_m *API) CreateCommand(cmd *model.Command) (*model.Command, error) { return r0, r1 } +// CreateOAuthApp provides a mock function with given fields: app +func (_m *API) CreateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + ret := _m.Called(app) + + var r0 *model.OAuthApp + if rf, ok := ret.Get(0).(func(*model.OAuthApp) *model.OAuthApp); ok { + r0 = rf(app) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.OAuthApp) + } + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func(*model.OAuthApp) *model.AppError); ok { + r1 = rf(app) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + // CreatePost provides a mock function with given fields: post func (_m *API) CreatePost(post *model.Post) (*model.Post, *model.AppError) { ret := _m.Called(post) @@ -366,6 +391,31 @@ func (_m *API) CreateUser(user *model.User) (*model.User, *model.AppError) { return r0, r1 } +// CreateUserAccessToken provides a mock function with given fields: token +func (_m *API) CreateUserAccessToken(token *model.UserAccessToken) (*model.UserAccessToken, *model.AppError) { + ret := _m.Called(token) + + var r0 *model.UserAccessToken + if rf, ok := ret.Get(0).(func(*model.UserAccessToken) *model.UserAccessToken); ok { + r0 = rf(token) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.UserAccessToken) + } + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func(*model.UserAccessToken) *model.AppError); ok { + r1 = rf(token) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + // DeleteBotIconImage provides a mock function with given fields: botUserId func (_m *API) DeleteBotIconImage(botUserId string) *model.AppError { ret := _m.Called(botUserId) @@ -433,6 +483,22 @@ func (_m *API) DeleteEphemeralPost(userID string, postId string) { _m.Called(userID, postId) } +// DeleteOAuthApp provides a mock function with given fields: appID +func (_m *API) DeleteOAuthApp(appID string) *model.AppError { + ret := _m.Called(appID) + + var r0 *model.AppError + if rf, ok := ret.Get(0).(func(string) *model.AppError); ok { + r0 = rf(appID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.AppError) + } + } + + return r0 +} + // DeletePost provides a mock function with given fields: postId func (_m *API) DeletePost(postId string) *model.AppError { ret := _m.Called(postId) @@ -1388,6 +1454,31 @@ func (_m *API) GetLicense() *model.License { return r0 } +// GetOAuthApp provides a mock function with given fields: appID +func (_m *API) GetOAuthApp(appID string) (*model.OAuthApp, *model.AppError) { + ret := _m.Called(appID) + + var r0 *model.OAuthApp + if rf, ok := ret.Get(0).(func(string) *model.OAuthApp); ok { + r0 = rf(appID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.OAuthApp) + } + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func(string) *model.AppError); ok { + r1 = rf(appID) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + // GetPluginConfig provides a mock function with given fields: func (_m *API) GetPluginConfig() map[string]interface{} { ret := _m.Called() @@ -2870,6 +2961,22 @@ func (_m *API) RequestTrialLicense(requesterID string, users int, termsAccepted return r0 } +// RevokeUserAccessToken provides a mock function with given fields: tokenID +func (_m *API) RevokeUserAccessToken(tokenID string) *model.AppError { + ret := _m.Called(tokenID) + + var r0 *model.AppError + if rf, ok := ret.Get(0).(func(string) *model.AppError); ok { + r0 = rf(tokenID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.AppError) + } + } + + return r0 +} + // SaveConfig provides a mock function with given fields: config func (_m *API) SaveConfig(config *model.Config) *model.AppError { ret := _m.Called(config) @@ -3310,6 +3417,31 @@ func (_m *API) UpdateEphemeralPost(userID string, post *model.Post) *model.Post return r0 } +// UpdateOAuthApp provides a mock function with given fields: app +func (_m *API) UpdateOAuthApp(app *model.OAuthApp) (*model.OAuthApp, *model.AppError) { + ret := _m.Called(app) + + var r0 *model.OAuthApp + if rf, ok := ret.Get(0).(func(*model.OAuthApp) *model.OAuthApp); ok { + r0 = rf(app) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.OAuthApp) + } + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func(*model.OAuthApp) *model.AppError); ok { + r1 = rf(app) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + // UpdatePost provides a mock function with given fields: post func (_m *API) UpdatePost(post *model.Post) (*model.Post, *model.AppError) { ret := _m.Called(post)