From 56e7bd01ca09ad52b0c4f48f146a20a4f1b78696 Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 5 Aug 2023 20:43:19 +0200 Subject: Update dependencies and remove old matterclient lib (#2067) --- .../v5/model/integration_action.go | 532 --------------------- 1 file changed, 532 deletions(-) delete mode 100644 vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go (limited to 'vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go') diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go b/vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go deleted file mode 100644 index 7124a7e3..00000000 --- a/vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go +++ /dev/null @@ -1,532 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package model - -import ( - "crypto" - "crypto/aes" - "crypto/cipher" - "crypto/ecdsa" - "crypto/rand" - "encoding/asn1" - "encoding/base64" - "encoding/json" - "fmt" - "io" - "math/big" - "net/http" - "reflect" - "strconv" - "strings" -) - -const ( - POST_ACTION_TYPE_BUTTON = "button" - POST_ACTION_TYPE_SELECT = "select" - INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS = 3000 -) - -var PostActionRetainPropKeys = []string{"from_webhook", "override_username", "override_icon_url"} - -type DoPostActionRequest struct { - SelectedOption string `json:"selected_option,omitempty"` - Cookie string `json:"cookie,omitempty"` -} - -type PostAction struct { - // A unique Action ID. If not set, generated automatically. - Id string `json:"id,omitempty"` - - // The type of the interactive element. Currently supported are - // "select" and "button". - Type string `json:"type,omitempty"` - - // The text on the button, or in the select placeholder. - Name string `json:"name,omitempty"` - - // If the action is disabled. - Disabled bool `json:"disabled,omitempty"` - - // Style defines a text and border style. - // Supported values are "default", "primary", "success", "good", "warning", "danger" - // and any hex color. - Style string `json:"style,omitempty"` - - // DataSource indicates the data source for the select action. If left - // empty, the select is populated from Options. Other supported values - // are "users" and "channels". - DataSource string `json:"data_source,omitempty"` - - // Options contains the values listed in a select dropdown on the post. - Options []*PostActionOptions `json:"options,omitempty"` - - // DefaultOption contains the option, if any, that will appear as the - // default selection in a select box. It has no effect when used with - // other types of actions. - DefaultOption string `json:"default_option,omitempty"` - - // Defines the interaction with the backend upon a user action. - // Integration contains Context, which is private plugin data; - // Integrations are stripped from Posts when they are sent to the - // client, or are encrypted in a Cookie. - Integration *PostActionIntegration `json:"integration,omitempty"` - Cookie string `json:"cookie,omitempty" db:"-"` -} - -func (p *PostAction) Equals(input *PostAction) bool { - if p.Id != input.Id { - return false - } - - if p.Type != input.Type { - return false - } - - if p.Name != input.Name { - return false - } - - if p.DataSource != input.DataSource { - return false - } - - if p.DefaultOption != input.DefaultOption { - return false - } - - if p.Cookie != input.Cookie { - return false - } - - // Compare PostActionOptions - if len(p.Options) != len(input.Options) { - return false - } - - for k := range p.Options { - if p.Options[k].Text != input.Options[k].Text { - return false - } - - if p.Options[k].Value != input.Options[k].Value { - return false - } - } - - // Compare PostActionIntegration - if p.Integration.URL != input.Integration.URL { - return false - } - - if len(p.Integration.Context) != len(input.Integration.Context) { - return false - } - - for key, value := range p.Integration.Context { - inputValue, ok := input.Integration.Context[key] - if !ok { - return false - } - - switch inputValue.(type) { - case string, bool, int, float64: - if value != inputValue { - return false - } - default: - if !reflect.DeepEqual(value, inputValue) { - return false - } - } - } - - return true -} - -// PostActionCookie is set by the server, serialized and encrypted into -// PostAction.Cookie. The clients should hold on to it, and include it with -// subsequent DoPostAction requests. This allows the server to access the -// action metadata even when it's not available in the database, for ephemeral -// posts. -type PostActionCookie struct { - Type string `json:"type,omitempty"` - PostId string `json:"post_id,omitempty"` - RootPostId string `json:"root_post_id,omitempty"` - ChannelId string `json:"channel_id,omitempty"` - DataSource string `json:"data_source,omitempty"` - Integration *PostActionIntegration `json:"integration,omitempty"` - RetainProps map[string]interface{} `json:"retain_props,omitempty"` - RemoveProps []string `json:"remove_props,omitempty"` -} - -type PostActionOptions struct { - Text string `json:"text"` - Value string `json:"value"` -} - -type PostActionIntegration struct { - URL string `json:"url,omitempty"` - Context map[string]interface{} `json:"context,omitempty"` -} - -type PostActionIntegrationRequest struct { - UserId string `json:"user_id"` - UserName string `json:"user_name"` - ChannelId string `json:"channel_id"` - ChannelName string `json:"channel_name"` - TeamId string `json:"team_id"` - TeamName string `json:"team_domain"` - PostId string `json:"post_id"` - TriggerId string `json:"trigger_id"` - Type string `json:"type"` - DataSource string `json:"data_source"` - Context map[string]interface{} `json:"context,omitempty"` -} - -type PostActionIntegrationResponse struct { - Update *Post `json:"update"` - EphemeralText string `json:"ephemeral_text"` - SkipSlackParsing bool `json:"skip_slack_parsing"` // Set to `true` to skip the Slack-compatibility handling of Text. -} - -type PostActionAPIResponse struct { - Status string `json:"status"` // needed to maintain backwards compatibility - TriggerId string `json:"trigger_id"` -} - -type Dialog struct { - CallbackId string `json:"callback_id"` - Title string `json:"title"` - IntroductionText string `json:"introduction_text"` - IconURL string `json:"icon_url"` - Elements []DialogElement `json:"elements"` - SubmitLabel string `json:"submit_label"` - NotifyOnCancel bool `json:"notify_on_cancel"` - State string `json:"state"` -} - -type DialogElement struct { - DisplayName string `json:"display_name"` - Name string `json:"name"` - Type string `json:"type"` - SubType string `json:"subtype"` - Default string `json:"default"` - Placeholder string `json:"placeholder"` - HelpText string `json:"help_text"` - Optional bool `json:"optional"` - MinLength int `json:"min_length"` - MaxLength int `json:"max_length"` - DataSource string `json:"data_source"` - Options []*PostActionOptions `json:"options"` -} - -type OpenDialogRequest struct { - TriggerId string `json:"trigger_id"` - URL string `json:"url"` - Dialog Dialog `json:"dialog"` -} - -type SubmitDialogRequest struct { - Type string `json:"type"` - URL string `json:"url,omitempty"` - CallbackId string `json:"callback_id"` - State string `json:"state"` - UserId string `json:"user_id"` - ChannelId string `json:"channel_id"` - TeamId string `json:"team_id"` - Submission map[string]interface{} `json:"submission"` - Cancelled bool `json:"cancelled"` -} - -type SubmitDialogResponse struct { - Error string `json:"error,omitempty"` - Errors map[string]string `json:"errors,omitempty"` -} - -func GenerateTriggerId(userId string, s crypto.Signer) (string, string, *AppError) { - clientTriggerId := NewId() - triggerData := strings.Join([]string{clientTriggerId, userId, strconv.FormatInt(GetMillis(), 10)}, ":") + ":" - - h := crypto.SHA256 - sum := h.New() - sum.Write([]byte(triggerData)) - signature, err := s.Sign(rand.Reader, sum.Sum(nil), h) - if err != nil { - return "", "", NewAppError("GenerateTriggerId", "interactive_message.generate_trigger_id.signing_failed", nil, err.Error(), http.StatusInternalServerError) - } - - base64Sig := base64.StdEncoding.EncodeToString(signature) - - triggerId := base64.StdEncoding.EncodeToString([]byte(triggerData + base64Sig)) - return clientTriggerId, triggerId, nil -} - -func (r *PostActionIntegrationRequest) GenerateTriggerId(s crypto.Signer) (string, string, *AppError) { - clientTriggerId, triggerId, err := GenerateTriggerId(r.UserId, s) - if err != nil { - return "", "", err - } - - r.TriggerId = triggerId - return clientTriggerId, triggerId, nil -} - -func DecodeAndVerifyTriggerId(triggerId string, s *ecdsa.PrivateKey) (string, string, *AppError) { - triggerIdBytes, err := base64.StdEncoding.DecodeString(triggerId) - if err != nil { - return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed", nil, err.Error(), http.StatusBadRequest) - } - - split := strings.Split(string(triggerIdBytes), ":") - if len(split) != 4 { - return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.missing_data", nil, "", http.StatusBadRequest) - } - - clientTriggerId := split[0] - userId := split[1] - timestampStr := split[2] - timestamp, _ := strconv.ParseInt(timestampStr, 10, 64) - - now := GetMillis() - if now-timestamp > INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS { - return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.expired", map[string]interface{}{"Seconds": INTERACTIVE_DIALOG_TRIGGER_TIMEOUT_MILLISECONDS / 1000}, "", http.StatusBadRequest) - } - - signature, err := base64.StdEncoding.DecodeString(split[3]) - if err != nil { - return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed_signature", nil, err.Error(), http.StatusBadRequest) - } - - var esig struct { - R, S *big.Int - } - - if _, err := asn1.Unmarshal(signature, &esig); err != nil { - return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.signature_decode_failed", nil, err.Error(), http.StatusBadRequest) - } - - triggerData := strings.Join([]string{clientTriggerId, userId, timestampStr}, ":") + ":" - - h := crypto.SHA256 - sum := h.New() - sum.Write([]byte(triggerData)) - - if !ecdsa.Verify(&s.PublicKey, sum.Sum(nil), esig.R, esig.S) { - return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.verify_signature_failed", nil, "", http.StatusBadRequest) - } - - return clientTriggerId, userId, nil -} - -func (r *OpenDialogRequest) DecodeAndVerifyTriggerId(s *ecdsa.PrivateKey) (string, string, *AppError) { - return DecodeAndVerifyTriggerId(r.TriggerId, s) -} - -func (r *PostActionIntegrationRequest) ToJson() []byte { - b, _ := json.Marshal(r) - return b -} - -func PostActionIntegrationRequestFromJson(data io.Reader) *PostActionIntegrationRequest { - var o *PostActionIntegrationRequest - err := json.NewDecoder(data).Decode(&o) - if err != nil { - return nil - } - return o -} - -func (r *PostActionIntegrationResponse) ToJson() []byte { - b, _ := json.Marshal(r) - return b -} - -func PostActionIntegrationResponseFromJson(data io.Reader) *PostActionIntegrationResponse { - var o *PostActionIntegrationResponse - err := json.NewDecoder(data).Decode(&o) - if err != nil { - return nil - } - return o -} - -func SubmitDialogRequestFromJson(data io.Reader) *SubmitDialogRequest { - var o *SubmitDialogRequest - err := json.NewDecoder(data).Decode(&o) - if err != nil { - return nil - } - return o -} - -func (r *SubmitDialogRequest) ToJson() []byte { - b, _ := json.Marshal(r) - return b -} - -func SubmitDialogResponseFromJson(data io.Reader) *SubmitDialogResponse { - var o *SubmitDialogResponse - err := json.NewDecoder(data).Decode(&o) - if err != nil { - return nil - } - return o -} - -func (r *SubmitDialogResponse) ToJson() []byte { - b, _ := json.Marshal(r) - return b -} - -func (o *Post) StripActionIntegrations() { - attachments := o.Attachments() - if o.GetProp("attachments") != nil { - o.AddProp("attachments", attachments) - } - for _, attachment := range attachments { - for _, action := range attachment.Actions { - action.Integration = nil - } - } -} - -func (o *Post) GetAction(id string) *PostAction { - for _, attachment := range o.Attachments() { - for _, action := range attachment.Actions { - if action != nil && action.Id == id { - return action - } - } - } - return nil -} - -func (o *Post) GenerateActionIds() { - if o.GetProp("attachments") != nil { - o.AddProp("attachments", o.Attachments()) - } - if attachments, ok := o.GetProp("attachments").([]*SlackAttachment); ok { - for _, attachment := range attachments { - for _, action := range attachment.Actions { - if action != nil && action.Id == "" { - action.Id = NewId() - } - } - } - } -} - -func AddPostActionCookies(o *Post, secret []byte) *Post { - p := o.Clone() - - // retainedProps carry over their value from the old post, including no value - retainProps := map[string]interface{}{} - removeProps := []string{} - for _, key := range PostActionRetainPropKeys { - value, ok := p.GetProps()[key] - if ok { - retainProps[key] = value - } else { - removeProps = append(removeProps, key) - } - } - - attachments := p.Attachments() - for _, attachment := range attachments { - for _, action := range attachment.Actions { - c := &PostActionCookie{ - Type: action.Type, - ChannelId: p.ChannelId, - DataSource: action.DataSource, - Integration: action.Integration, - RetainProps: retainProps, - RemoveProps: removeProps, - } - - c.PostId = p.Id - if p.RootId == "" { - c.RootPostId = p.Id - } else { - c.RootPostId = p.RootId - } - - b, _ := json.Marshal(c) - action.Cookie, _ = encryptPostActionCookie(string(b), secret) - } - } - - return p -} - -func encryptPostActionCookie(plain string, secret []byte) (string, error) { - if len(secret) == 0 { - return plain, nil - } - - block, err := aes.NewCipher(secret) - if err != nil { - return "", err - } - - aesgcm, err := cipher.NewGCM(block) - if err != nil { - return "", err - } - - nonce := make([]byte, aesgcm.NonceSize()) - _, err = io.ReadFull(rand.Reader, nonce) - if err != nil { - return "", err - } - - sealed := aesgcm.Seal(nil, nonce, []byte(plain), nil) - - combined := append(nonce, sealed...) - encoded := make([]byte, base64.StdEncoding.EncodedLen(len(combined))) - base64.StdEncoding.Encode(encoded, combined) - - return string(encoded), nil -} - -func DecryptPostActionCookie(encoded string, secret []byte) (string, error) { - if len(secret) == 0 { - return encoded, nil - } - - block, err := aes.NewCipher(secret) - if err != nil { - return "", err - } - - aesgcm, err := cipher.NewGCM(block) - if err != nil { - return "", err - } - - decoded := make([]byte, base64.StdEncoding.DecodedLen(len(encoded))) - n, err := base64.StdEncoding.Decode(decoded, []byte(encoded)) - if err != nil { - return "", err - } - decoded = decoded[:n] - - nonceSize := aesgcm.NonceSize() - if len(decoded) < nonceSize { - return "", fmt.Errorf("cookie too short") - } - - nonce, decoded := decoded[:nonceSize], decoded[nonceSize:] - plain, err := aesgcm.Open(nil, nonce, decoded, nil) - if err != nil { - return "", err - } - - return string(plain), nil -} - -func DoPostActionRequestFromJson(data io.Reader) *DoPostActionRequest { - var o *DoPostActionRequest - json.NewDecoder(data).Decode(&o) - return o -} -- cgit v1.2.3