Files
golib/mail/config.go
nabbar c4b5f11efc Rework ioutils/gzipreader/fileprogress
Package ioutils:
- remove file progress from ioutils and rework it to package
  file/progress

Package file/progress:
- simplify call / use of file progress
- optimize code
- use atomic to function progress
- isolation part of code
- make interface more compatible with *os/File / io interface

Package archive/gzipreader
- create package to expose a io.reader interface from a no gzipped io.reader
- add interface GZipReader to expose metrics like rate of compression

Package archive:
- apply following change
- add minor internal change into errors files

Package artifact:
- apply following change
- add minor internal change into errors files

Package aws:
- apply following change
- removing minio server from repo

Package mail:
- apply following change
- add minor internal change into errors files

Package nutsdb:
- apply following change
- add minor internal change into errors files

Package static:
- apply following change

Other:
- bump dependencies
- ci/cd : add a wget command to dl minio server for testing
- add aws/minio to gitignore
2023-08-22 19:42:46 +02:00

192 lines
6.6 KiB
Go

/*
* MIT License
*
* Copyright (c) 2021 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*
*/
package mail
import (
"fmt"
"net/textproto"
libval "github.com/go-playground/validator/v10"
liberr "github.com/nabbar/golib/errors"
libfpg "github.com/nabbar/golib/file/progress"
)
type Config struct {
// Charset is the charset to use into mail header
Charset string `json:"charset" yaml:"charset" toml:"charset" mapstructure:"charset" validate:"required"`
// Subject is the subject of the mail
Subject string `json:"subject" yaml:"subject" toml:"subject" mapstructure:"subject" validate:"required"`
// Encoding is the encoding mode for contents of mail
Encoding string `json:"encoding" yaml:"encoding" toml:"encoding" mapstructure:"encoding" validate:"required"`
// Priority is priority of the mail
Priority string `json:"priority" yaml:"priority" toml:"priority" mapstructure:"priority" validate:"required"`
// Header is list of header couple like key = value to be added into mail header
Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty" toml:"headers,omitempty" mapstructure:"headers,omitempty"`
// From is the email use for sending the mail.
// If Sender is not set, it will be used as sender into.
// If ReplyTo is not set, it will be used for the reply email.
From string `json:"from" yaml:"from" toml:"from" mapstructure:"from" validate:"required,email"`
// Sender is used to specify the email show as sender.
// If From is not set, this value will be used as From email.
// If ReplyTo is not set, it will be used for the reply email.
Sender string `json:"sender,omitempty" yaml:"sender,omitempty" toml:"sender,omitempty" mapstructure:"sender,omitempty" validate:"email"`
// ReplyTo is used to specify the email to use for reply.
// If From is not set, this value will be used as From email.
// If Sender is not set, it will be used as sender into.
ReplyTo string `json:"replyTo,omitempty" yaml:"replyTo,omitempty" toml:"replyTo,omitempty" mapstructure:"replyTo,omitempty" validate:"email"`
// ReturnPath allow to specify the return path, usefull is the ip sender is not public to specify the method to contact the mail server
ReturnPath string `json:"returnPath,omitempty" yaml:"returnPath,omitempty" toml:"returnPath,omitempty" mapstructure:"returnPath,omitempty"`
// To is a list of email who the direct recipient of mail.
To []string `json:"to,omitempty" yaml:"to,omitempty" toml:"to,omitempty" mapstructure:"to,omitempty" validate:"dive,email"`
// Cc is a list of email who the copy recipient of mail.
Cc []string `json:"cc,omitempty" yaml:"cc,omitempty" toml:"cc,omitempty" mapstructure:"cc,omitempty" validate:"dive,email"`
// Bcc is a list of email who in copy recipient of mail but not listed in any field of the mail or headers of the mail.
Bcc []string `json:"bcc,omitempty" yaml:"bcc,omitempty" toml:"bcc,omitempty" mapstructure:"bcc,omitempty" validate:"dive,email"`
// Attach define a list of file to be attached to the mail
Attach []ConfigFile `json:"attach,omitempty" yaml:"attach,omitempty" toml:"attach,omitempty" mapstructure:"attach,omitempty" validate:"dive"`
// Inline define a list of file to be attached to the mail, but inline the body of the mail and not as mail attachment
Inline []ConfigFile `json:"inline,omitempty" yaml:"inline,omitempty" toml:"inline,omitempty" mapstructure:"inline,omitempty" validate:"dive"`
}
type ConfigFile struct {
Name string `json:"name" yaml:"name" toml:"name" mapstructure:"name" validate:"required"`
Mime string `json:"mime" yaml:"mime" toml:"mime" mapstructure:"mime" validate:"required"`
Path string `json:"path" yaml:"path" toml:"path" mapstructure:"path" validate:"required,file"`
}
func (c Config) Validate() liberr.Error {
err := ErrorMailConfigInvalid.Error(nil)
if er := libval.New().Struct(c); er != nil {
if e, ok := er.(*libval.InvalidValidationError); ok {
err.AddParent(e)
}
for _, e := range er.(libval.ValidationErrors) {
//nolint goerr113
err.AddParent(fmt.Errorf("config field '%s' is not validated by constraint '%s'", e.Namespace(), e.ActualTag()))
}
}
if err.HasParent() {
return err
}
return nil
}
func (c Config) NewMailer() (Mail, liberr.Error) {
m := &mail{
headers: make(textproto.MIMEHeader),
charset: "UTF-8",
encoding: ParseEncoding(c.Encoding),
priority: ParsePriority(c.Priority),
address: &email{
from: "",
sender: "",
replyTo: "",
returnPath: "",
to: make([]string, 0),
cc: make([]string, 0),
bcc: make([]string, 0),
},
attach: make([]File, 0),
inline: make([]File, 0),
body: make([]Body, 0),
}
m.headers.Set("MIME-Version", "1.0")
if len(c.Headers) > 0 {
for k, v := range c.Headers {
m.headers.Set(k, v)
}
}
if c.Charset != "" {
m.charset = c.Charset
}
m.Email().SetFrom(c.From)
if c.Sender != "" {
m.Email().SetSender(c.Sender)
}
if c.Sender != "" {
m.Email().SetReplyTo(c.ReplyTo)
}
if c.Sender != "" {
m.Email().SetReturnPath(c.ReturnPath)
}
if len(c.To) > 0 {
m.Email().AddRecipients(RecipientTo, c.To...)
}
if len(c.Cc) > 0 {
m.Email().AddRecipients(RecipientCC, c.Cc...)
}
if len(c.Bcc) > 0 {
m.Email().AddRecipients(RecipientBCC, c.Bcc...)
}
if len(c.Attach) > 0 {
for _, f := range c.Attach {
if h, e := libfpg.Open(f.Path); e != nil {
return nil, ErrorFileOpenCreate.ErrorParent(e)
} else {
m.AddAttachment(f.Name, f.Mime, h, false)
}
}
}
if len(c.Inline) > 0 {
for _, f := range c.Inline {
if h, e := libfpg.Open(f.Path); e != nil {
return nil, ErrorFileOpenCreate.ErrorParent(e)
} else {
m.AddAttachment(f.Name, f.Mime, h, true)
}
}
}
return m, nil
}