github.com/vnforks/kid@v5.11.1+incompatible/services/mailservice/inbucket.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package mailservice 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) (JSONMessageInbucket, error) { 93 parsedEmail := ParseEmail(email) 94 95 var record JSONMessageInbucket 96 97 url := fmt.Sprintf("%s%s%s/%s", getInbucketHost(), INBUCKET_API, parsedEmail, id) 98 emailResponse, err := get(url) 99 if err != nil { 100 return record, err 101 } 102 defer emailResponse.Body.Close() 103 104 if err = json.NewDecoder(emailResponse.Body).Decode(&record); err != nil { 105 return record, err 106 } 107 108 // download attachments 109 if record.Attachments != nil && len(record.Attachments) > 0 { 110 for i := range record.Attachments { 111 var bytes []byte 112 bytes, err = downloadAttachment(record.Attachments[i].DownloadLink) 113 if err != nil { 114 return record, err 115 } 116 record.Attachments[i].Bytes = make([]byte, len(bytes)) 117 copy(record.Attachments[i].Bytes, bytes) 118 } 119 } 120 121 return record, err 122 } 123 124 func downloadAttachment(url string) ([]byte, error) { 125 attachmentResponse, err := get(url) 126 if err != nil { 127 return nil, err 128 } 129 defer attachmentResponse.Body.Close() 130 131 buf := new(bytes.Buffer) 132 io.Copy(buf, attachmentResponse.Body) 133 return buf.Bytes(), nil 134 } 135 136 func get(url string) (*http.Response, error) { 137 req, err := http.NewRequest("GET", url, nil) 138 if err != nil { 139 return nil, err 140 } 141 142 client := &http.Client{} 143 resp, err := client.Do(req) 144 if err != nil { 145 return nil, err 146 } 147 148 return resp, nil 149 } 150 151 func DeleteMailBox(email string) (err error) { 152 153 parsedEmail := ParseEmail(email) 154 155 url := fmt.Sprintf("%s%s%s", getInbucketHost(), INBUCKET_API, parsedEmail) 156 req, err := http.NewRequest("DELETE", url, nil) 157 if err != nil { 158 return err 159 } 160 161 client := &http.Client{} 162 163 resp, err := client.Do(req) 164 if err != nil { 165 return err 166 } 167 defer resp.Body.Close() 168 169 return nil 170 } 171 172 func RetryInbucket(attempts int, callback func() error) (err error) { 173 for i := 0; ; i++ { 174 err = callback() 175 if err == nil { 176 return nil 177 } 178 179 if i >= (attempts - 1) { 180 break 181 } 182 183 time.Sleep(5 * time.Second) 184 185 fmt.Println("retrying...") 186 } 187 return fmt.Errorf("After %d attempts, last error: %s", attempts, err) 188 } 189 190 func getInbucketHost() (host string) { 191 192 inbucket_host := os.Getenv("CI_INBUCKET_HOST") 193 if inbucket_host == "" { 194 inbucket_host = "dockerhost" 195 } 196 197 inbucket_port := os.Getenv("CI_INBUCKET_PORT") 198 if inbucket_port == "" { 199 inbucket_port = "9000" 200 } 201 return fmt.Sprintf("http://%s:%s", inbucket_host, inbucket_port) 202 }