github.com/levb/mattermost-server@v5.3.1+incompatible/utils/inbucket.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package utils 5 6 import ( 7 "bytes" 8 "encoding/json" 9 "fmt" 10 "io" 11 "net/http" 12 "os" 13 "strings" 14 "time" 15 ) 16 17 const ( 18 INBUCKET_API = "/api/v1/mailbox/" 19 ) 20 21 // OutputJSONHeader holds the received Header to test sending emails (inbucket) 22 type JSONMessageHeaderInbucket []struct { 23 Mailbox string 24 ID string `json:"Id"` 25 From, Subject, Date string 26 To []string 27 Size int 28 } 29 30 // OutputJSONMessage holds the received Message fto test sending emails (inbucket) 31 type JSONMessageInbucket struct { 32 Mailbox string 33 ID string `json:"Id"` 34 From, Subject, Date string 35 Size int 36 Header map[string][]string 37 Body struct { 38 Text string 39 HTML string `json:"Html"` 40 } 41 Attachments []struct { 42 Filename string 43 ContentType string `json:"content-type"` 44 DownloadLink string `json:"download-link"` 45 Bytes []byte `json:"-"` 46 } 47 } 48 49 func ParseEmail(email string) string { 50 pos := strings.Index(email, "@") 51 parsedEmail := email[0:pos] 52 return parsedEmail 53 } 54 55 func GetMailBox(email string) (results JSONMessageHeaderInbucket, err error) { 56 57 parsedEmail := ParseEmail(email) 58 59 url := fmt.Sprintf("%s%s%s", getInbucketHost(), INBUCKET_API, parsedEmail) 60 req, err := http.NewRequest("GET", url, nil) 61 if err != nil { 62 return nil, err 63 } 64 65 client := &http.Client{} 66 67 resp, err := client.Do(req) 68 if err != nil { 69 return nil, err 70 } 71 defer resp.Body.Close() 72 73 if resp.Body == nil { 74 return nil, fmt.Errorf("No Mailbox") 75 } 76 77 var record JSONMessageHeaderInbucket 78 err = json.NewDecoder(resp.Body).Decode(&record) 79 switch { 80 case err == io.EOF: 81 return nil, fmt.Errorf("Error: %s", err) 82 case err != nil: 83 return nil, fmt.Errorf("Error: %s", err) 84 } 85 if len(record) == 0 { 86 return nil, fmt.Errorf("No mailbox") 87 } 88 89 return record, nil 90 } 91 92 func GetMessageFromMailbox(email, id string) (results JSONMessageInbucket, err error) { 93 94 parsedEmail := ParseEmail(email) 95 96 var record JSONMessageInbucket 97 98 url := fmt.Sprintf("%s%s%s/%s", getInbucketHost(), INBUCKET_API, parsedEmail, id) 99 emailResponse, err := get(url) 100 if err != nil { 101 return record, err 102 } 103 defer emailResponse.Body.Close() 104 105 err = json.NewDecoder(emailResponse.Body).Decode(&record) 106 107 // download attachments 108 if record.Attachments != nil && len(record.Attachments) > 0 { 109 for i := range record.Attachments { 110 if bytes, err := downloadAttachment(record.Attachments[i].DownloadLink); err != nil { 111 return record, err 112 } else { 113 record.Attachments[i].Bytes = make([]byte, len(bytes)) 114 copy(record.Attachments[i].Bytes, bytes) 115 } 116 } 117 } 118 119 return record, err 120 } 121 122 func downloadAttachment(url string) ([]byte, error) { 123 attachmentResponse, err := get(url) 124 if err != nil { 125 return nil, err 126 } 127 defer attachmentResponse.Body.Close() 128 129 buf := new(bytes.Buffer) 130 io.Copy(buf, attachmentResponse.Body) 131 return buf.Bytes(), nil 132 } 133 134 func get(url string) (*http.Response, error) { 135 req, err := http.NewRequest("GET", url, nil) 136 if err != nil { 137 return nil, err 138 } 139 140 client := &http.Client{} 141 resp, err := client.Do(req) 142 if err != nil { 143 return nil, err 144 } 145 146 return resp, nil 147 } 148 149 func DeleteMailBox(email string) (err error) { 150 151 parsedEmail := ParseEmail(email) 152 153 url := fmt.Sprintf("%s%s%s", getInbucketHost(), INBUCKET_API, parsedEmail) 154 req, err := http.NewRequest("DELETE", url, nil) 155 if err != nil { 156 return err 157 } 158 159 client := &http.Client{} 160 161 resp, err := client.Do(req) 162 if err != nil { 163 return err 164 } 165 defer resp.Body.Close() 166 167 return nil 168 } 169 170 func RetryInbucket(attempts int, callback func() error) (err error) { 171 for i := 0; ; i++ { 172 err = callback() 173 if err == nil { 174 return nil 175 } 176 177 if i >= (attempts - 1) { 178 break 179 } 180 181 time.Sleep(5 * time.Second) 182 183 fmt.Println("retrying...") 184 } 185 return fmt.Errorf("After %d attempts, last error: %s", attempts, err) 186 } 187 188 func getInbucketHost() (host string) { 189 190 inbucket_host := os.Getenv("CI_HOST") 191 if inbucket_host == "" { 192 inbucket_host = "dockerhost" 193 } 194 195 inbucket_port := os.Getenv("CI_INBUCKET_PORT") 196 if inbucket_port == "" { 197 inbucket_port = "9000" 198 } 199 return fmt.Sprintf("http://%s:%s", inbucket_host, inbucket_port) 200 }