snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
This commit is contained in:
397
server/channels/api4/outgoing_oauth_connection.go
Normal file
397
server/channels/api4/outgoing_oauth_connection.go
Normal file
@@ -0,0 +1,397 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package api4
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/mattermost/logr/v2"
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/v8/einterfaces"
|
||||
)
|
||||
|
||||
const (
|
||||
whereOutgoingOAuthConnection = "outgoingOAuthConnections"
|
||||
)
|
||||
|
||||
func (api *API) InitOutgoingOAuthConnection() {
|
||||
api.BaseRoutes.OutgoingOAuthConnections.Handle("", api.APISessionRequired(listOutgoingOAuthConnections)).Methods(http.MethodGet)
|
||||
api.BaseRoutes.OutgoingOAuthConnections.Handle("", api.APISessionRequired(createOutgoingOAuthConnection)).Methods(http.MethodPost)
|
||||
api.BaseRoutes.OutgoingOAuthConnection.Handle("", api.APISessionRequired(getOutgoingOAuthConnection)).Methods(http.MethodGet)
|
||||
api.BaseRoutes.OutgoingOAuthConnection.Handle("", api.APISessionRequired(updateOutgoingOAuthConnection)).Methods(http.MethodPut)
|
||||
api.BaseRoutes.OutgoingOAuthConnection.Handle("", api.APISessionRequired(deleteOutgoingOAuthConnection)).Methods(http.MethodDelete)
|
||||
api.BaseRoutes.OutgoingOAuthConnections.Handle("/validate", api.APISessionRequired(validateOutgoingOAuthConnectionCredentials)).Methods(http.MethodPost)
|
||||
}
|
||||
|
||||
// checkOutgoingOAuthConnectionReadPermissions checks if the user has the permissions to read outgoing oauth connections.
|
||||
// An user with the permissions to manage outgoing oauth connections can read outgoing oauth connections.
|
||||
// Otherwise the user needs to have the permissions to manage outgoing webhooks or slash commands in order to read outgoing
|
||||
// oauth connections so that they can use them.
|
||||
// This is made in this way so only users with the management permission can setup the outgoing oauth connections and then
|
||||
// other users can use them in their outgoing webhooks and slash commands if they have permissions to manage those.
|
||||
func checkOutgoingOAuthConnectionReadPermissions(c *Context, teamId string) bool {
|
||||
if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOutgoingOAuthConnections) ||
|
||||
c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOwnOutgoingWebhooks) ||
|
||||
c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageOwnSlashCommands) {
|
||||
return true
|
||||
}
|
||||
|
||||
c.SetPermissionError(model.PermissionManageOwnOutgoingWebhooks, model.PermissionManageOwnSlashCommands)
|
||||
return false
|
||||
}
|
||||
|
||||
// checkOutgoingOAuthConnectionWritePermissions checks if the user has the permissions to write outgoing oauth connections.
|
||||
// This is a more granular permissions intended for system admins to manage (setup) outgoing oauth connections.
|
||||
func checkOutgoingOAuthConnectionWritePermissions(c *Context) bool {
|
||||
if c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOutgoingOAuthConnections) {
|
||||
return true
|
||||
}
|
||||
|
||||
c.SetPermissionError(model.PermissionManageOutgoingOAuthConnections)
|
||||
return false
|
||||
}
|
||||
|
||||
func ensureOutgoingOAuthConnectionInterface(c *Context, where string) (einterfaces.OutgoingOAuthConnectionInterface, bool) {
|
||||
if c.App.Config().ServiceSettings.EnableOutgoingOAuthConnections != nil && !*c.App.Config().ServiceSettings.EnableOutgoingOAuthConnections {
|
||||
c.Err = model.NewAppError(where, "api.context.outgoing_oauth_connection.not_available.configuration_disabled", nil, "", http.StatusNotImplemented)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if c.App.OutgoingOAuthConnections() == nil || !model.MinimumEnterpriseLicense(c.App.License()) {
|
||||
c.Err = model.NewAppError(where, "api.license.upgrade_needed.app_error", nil, "", http.StatusNotImplemented)
|
||||
return nil, false
|
||||
}
|
||||
return c.App.OutgoingOAuthConnections(), true
|
||||
}
|
||||
|
||||
type listOutgoingOAuthConnectionsQuery struct {
|
||||
FromID string
|
||||
Limit int
|
||||
Audience string
|
||||
}
|
||||
|
||||
// SetDefaults sets the default values for the query.
|
||||
func (q *listOutgoingOAuthConnectionsQuery) SetDefaults() {
|
||||
// Set default values
|
||||
if q.Limit == 0 {
|
||||
q.Limit = 10
|
||||
}
|
||||
}
|
||||
|
||||
// IsValid validates the query.
|
||||
func (q *listOutgoingOAuthConnectionsQuery) IsValid() error {
|
||||
if q.Limit < 1 || q.Limit > 100 {
|
||||
return fmt.Errorf("limit must be between 1 and 100")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToFilter converts the query to a filter that can be used to query the database.
|
||||
func (q *listOutgoingOAuthConnectionsQuery) ToFilter() model.OutgoingOAuthConnectionGetConnectionsFilter {
|
||||
return model.OutgoingOAuthConnectionGetConnectionsFilter{
|
||||
OffsetId: q.FromID,
|
||||
Limit: q.Limit,
|
||||
Audience: q.Audience,
|
||||
}
|
||||
}
|
||||
|
||||
func NewListOutgoingOAuthConnectionsQueryFromURLQuery(values url.Values) (*listOutgoingOAuthConnectionsQuery, error) {
|
||||
query := &listOutgoingOAuthConnectionsQuery{}
|
||||
query.SetDefaults()
|
||||
|
||||
fromID := values.Get("from_id")
|
||||
if fromID != "" {
|
||||
query.FromID = fromID
|
||||
}
|
||||
|
||||
limit := values.Get("limit")
|
||||
if limit != "" {
|
||||
limitInt, err := strconv.Atoi(limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query.Limit = limitInt
|
||||
}
|
||||
|
||||
audience := values.Get("audience")
|
||||
if audience != "" {
|
||||
query.Audience = audience
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
func listOutgoingOAuthConnections(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
teamId := r.URL.Query().Get("team_id")
|
||||
if !checkOutgoingOAuthConnectionReadPermissions(c, teamId) {
|
||||
return
|
||||
}
|
||||
|
||||
service, ok := ensureOutgoingOAuthConnectionInterface(c, whereOutgoingOAuthConnection)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
query, err := NewListOutgoingOAuthConnectionsQueryFromURLQuery(r.URL.Query())
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.list_connections.input_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
if errValid := query.IsValid(); errValid != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.list_connections.input_error", nil, "", http.StatusBadRequest).Wrap(errValid)
|
||||
return
|
||||
}
|
||||
|
||||
var connections []*model.OutgoingOAuthConnection
|
||||
if query.Audience != "" {
|
||||
// If the consumer expects an audience match, use the `GetConnectionByAudience` method to
|
||||
// retrieve a single connection.
|
||||
connection, err := service.GetConnectionForAudience(c.AppContext, query.Audience)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.list_connections.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
connections = append(connections, connection)
|
||||
} else {
|
||||
// If the consumer does not expect an audience match, use the `GetConnections` method to
|
||||
// retrieve a list of connections that potentially matches the provided audience.
|
||||
var errList *model.AppError
|
||||
connections, errList = service.GetConnections(c.AppContext, query.ToFilter())
|
||||
if errList != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.list_connections.app_error", nil, "", http.StatusInternalServerError).Wrap(errList)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
service.SanitizeConnections(connections)
|
||||
|
||||
if errJSON := json.NewEncoder(w).Encode(connections); errJSON != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.list_connections.app_error", nil, "", http.StatusInternalServerError).Wrap(errJSON)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func getOutgoingOAuthConnection(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !checkOutgoingOAuthConnectionWritePermissions(c) {
|
||||
return
|
||||
}
|
||||
|
||||
service, ok := ensureOutgoingOAuthConnectionInterface(c, whereOutgoingOAuthConnection)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.RequireOutgoingOAuthConnectionId()
|
||||
|
||||
connection, err := service.GetConnection(c.AppContext, c.Params.OutgoingOAuthConnectionID)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.list_connections.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
service.SanitizeConnection(connection)
|
||||
|
||||
if err := json.NewEncoder(w).Encode(connection); err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.list_connections.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func createOutgoingOAuthConnection(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord(model.AuditEventCreateOutgoingOauthConnection, model.AuditStatusFail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !checkOutgoingOAuthConnectionWritePermissions(c) {
|
||||
return
|
||||
}
|
||||
|
||||
service, ok := ensureOutgoingOAuthConnectionInterface(c, whereOutgoingOAuthConnection)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var inputConnection model.OutgoingOAuthConnection
|
||||
if err := json.NewDecoder(r.Body).Decode(&inputConnection); err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.create_connection.input_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
model.AddEventParameterAuditableToAuditRec(auditRec, "outgoing_oauth_connection", &inputConnection)
|
||||
|
||||
inputConnection.CreatorId = c.AppContext.Session().UserId
|
||||
|
||||
connection, err := service.SaveConnection(c.AppContext, &inputConnection)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.create_connection.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
auditRec.AddEventResultState(connection)
|
||||
auditRec.AddEventObjectType("outgoing_oauth_connection")
|
||||
c.LogAudit("client_id=" + connection.ClientId)
|
||||
|
||||
service.SanitizeConnection(connection)
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
if err := json.NewEncoder(w).Encode(connection); err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.create_connection.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func updateOutgoingOAuthConnection(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord(model.AuditEventUpdateOutgoingOAuthConnection, model.AuditStatusFail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
model.AddEventParameterToAuditRec(auditRec, "outgoing_oauth_connection_id", c.Params.OutgoingOAuthConnectionID)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !checkOutgoingOAuthConnectionWritePermissions(c) {
|
||||
return
|
||||
}
|
||||
|
||||
service, ok := ensureOutgoingOAuthConnectionInterface(c, whereOutgoingOAuthConnection)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.RequireOutgoingOAuthConnectionId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var inputConnection model.OutgoingOAuthConnection
|
||||
if err := json.NewDecoder(r.Body).Decode(&inputConnection); err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.update_connection.input_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
if inputConnection.Id != c.Params.OutgoingOAuthConnectionID {
|
||||
c.SetInvalidParam("id")
|
||||
return
|
||||
}
|
||||
|
||||
currentConnection, err := service.GetConnection(c.AppContext, c.Params.OutgoingOAuthConnectionID)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.update_connection.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
auditRec.AddEventPriorState(currentConnection)
|
||||
|
||||
currentConnection.Patch(&inputConnection)
|
||||
|
||||
connection, err := service.UpdateConnection(c.AppContext, currentConnection)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.update_connection.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.AddEventObjectType("outgoing_oauth_connection")
|
||||
auditRec.AddEventResultState(connection)
|
||||
auditRec.Success()
|
||||
auditLogExtraInfo := "success"
|
||||
// Audit log changes to clientID/Client Secret
|
||||
if connection.ClientId != currentConnection.ClientId {
|
||||
auditLogExtraInfo += " new_client_id=" + connection.ClientId
|
||||
}
|
||||
if connection.ClientSecret != currentConnection.ClientSecret {
|
||||
auditLogExtraInfo += " new_client_secret"
|
||||
}
|
||||
c.LogAudit(auditLogExtraInfo)
|
||||
service.SanitizeConnection(connection)
|
||||
|
||||
if err := json.NewEncoder(w).Encode(connection); err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.update_connection.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func deleteOutgoingOAuthConnection(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord(model.AuditEventDeleteOutgoingOAuthConnection, model.AuditStatusFail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
model.AddEventParameterToAuditRec(auditRec, "outgoing_oauth_connection_id", c.Params.OutgoingOAuthConnectionID)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !checkOutgoingOAuthConnectionWritePermissions(c) {
|
||||
return
|
||||
}
|
||||
|
||||
service, ok := ensureOutgoingOAuthConnectionInterface(c, whereOutgoingOAuthConnection)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.RequireOutgoingOAuthConnectionId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
connection, err := service.GetConnection(c.AppContext, c.Params.OutgoingOAuthConnectionID)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.delete_connection.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
auditRec.AddEventPriorState(connection)
|
||||
|
||||
if err := service.DeleteConnection(c.AppContext, c.Params.OutgoingOAuthConnectionID); err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.delete_connection.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.AddEventObjectType("outgoing_oauth_connection")
|
||||
auditRec.Success()
|
||||
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
// validateOutgoingOAuthConnectionCredentials validates the credentials of an outgoing oauth connection by requesting a token
|
||||
// with the provided connection configuration. If the credentials are valid, the request will return a 200 status code and
|
||||
// if the credentials are invalid, the request will return a 400 status code.
|
||||
func validateOutgoingOAuthConnectionCredentials(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := c.MakeAuditRecord(model.AuditEventValidateOutgoingOAuthConnectionCredentials, model.AuditStatusFail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
c.LogAudit("attempt")
|
||||
|
||||
if !checkOutgoingOAuthConnectionWritePermissions(c) {
|
||||
return
|
||||
}
|
||||
|
||||
service, ok := ensureOutgoingOAuthConnectionInterface(c, whereOutgoingOAuthConnection)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Allow checking connections sent in the body or by id if coming from an already existing
|
||||
// connection url.
|
||||
var inputConnection *model.OutgoingOAuthConnection
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&inputConnection); err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.validate_connection_credentials.input_error", nil, "", http.StatusBadRequest).Wrap(err)
|
||||
w.WriteHeader(c.Err.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
model.AddEventParameterAuditableToAuditRec(auditRec, "outgoing_oauth_connection", inputConnection)
|
||||
|
||||
// Try to retrieve a token with the provided credentials
|
||||
// do not store the token, just check if the credentials are valid and the request can be made
|
||||
_, err := service.RetrieveTokenForConnection(c.AppContext, inputConnection)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError(whereOutgoingOAuthConnection, "api.context.outgoing_oauth_connection.validate_connection_credentials.app_error", nil, "", err.StatusCode).Wrap(err)
|
||||
c.Logger.Error("Failed to retrieve token while validating outgoing oauth connection", logr.Err(err))
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
auditRec.AddEventResultState(inputConnection)
|
||||
auditRec.AddEventObjectType("outgoing_oauth_connection")
|
||||
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
Reference in New Issue
Block a user