mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-23 06:10:48 +01:00
Compare commits
9 commits
c01e7964c3
...
1e3f4fe757
Author | SHA1 | Date | |
---|---|---|---|
|
1e3f4fe757 | ||
|
3154649420 | ||
|
65b9fd07da | ||
077c85bea0 | |||
909e699b99 | |||
|
b97073db19 | ||
|
d75d990124 | ||
0676d99f20 | |||
|
d6725b2d63 |
8 changed files with 55 additions and 100 deletions
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
|
@ -54,7 +54,7 @@ jobs:
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
|
uses: github/codeql-action/init@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
@ -65,7 +65,7 @@ jobs:
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
|
uses: github/codeql-action/autobuild@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
|
@ -79,4 +79,4 @@ jobs:
|
||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
|
uses: github/codeql-action/analyze@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9
|
||||||
|
|
2
.github/workflows/scorecards.yml
vendored
2
.github/workflows/scorecards.yml
vendored
|
@ -75,6 +75,6 @@ jobs:
|
||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
|
uses: github/codeql-action/upload-sarif@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|
2
.github/workflows/sonarqube.yml
vendored
2
.github/workflows/sonarqube.yml
vendored
|
@ -44,7 +44,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
go test -v -race --coverprofile=./cov.out ./...
|
go test -v -race --coverprofile=./cov.out ./...
|
||||||
|
|
||||||
- uses: sonarsource/sonarqube-scan-action@0c0f3958d90fc466625f1d1af1f47bddd4cc6bd1 # master
|
- uses: sonarsource/sonarqube-scan-action@884b79409bbd464b2a59edc326a4b77dc56b2195 # master
|
||||||
env:
|
env:
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||||
|
|
13
encoding.go
13
encoding.go
|
@ -19,9 +19,6 @@ type MIMEVersion string
|
||||||
// MIMEType represents the MIME type for the mail
|
// MIMEType represents the MIME type for the mail
|
||||||
type MIMEType string
|
type MIMEType string
|
||||||
|
|
||||||
// Disposition represents a content disposition for the Msg
|
|
||||||
type Disposition string
|
|
||||||
|
|
||||||
// List of supported encodings
|
// List of supported encodings
|
||||||
const (
|
const (
|
||||||
// EncodingB64 represents the Base64 encoding as specified in RFC 2045.
|
// EncodingB64 represents the Base64 encoding as specified in RFC 2045.
|
||||||
|
@ -163,11 +160,6 @@ const (
|
||||||
MIMESMime MIMEType = `signed; protocol="application/pkcs7-signature"; micalg=sha256`
|
MIMESMime MIMEType = `signed; protocol="application/pkcs7-signature"; micalg=sha256`
|
||||||
)
|
)
|
||||||
|
|
||||||
// List of common content disposition
|
|
||||||
const (
|
|
||||||
DispositionSMime Disposition = `attachment; filename="smime.p7s"`
|
|
||||||
)
|
|
||||||
|
|
||||||
// String is a standard method to convert an Charset into a printable format
|
// String is a standard method to convert an Charset into a printable format
|
||||||
func (c Charset) String() string {
|
func (c Charset) String() string {
|
||||||
return string(c)
|
return string(c)
|
||||||
|
@ -182,8 +174,3 @@ func (c ContentType) String() string {
|
||||||
func (e Encoding) String() string {
|
func (e Encoding) String() string {
|
||||||
return string(e)
|
return string(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// String is a standard method to convert an Disposition into a printable format
|
|
||||||
func (d Disposition) String() string {
|
|
||||||
return string(d)
|
|
||||||
}
|
|
||||||
|
|
|
@ -126,22 +126,3 @@ func TestCharset_String(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDisposition_String tests the string method of the Disposition object
|
|
||||||
func TestDisposition_String(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
d Disposition
|
|
||||||
want string
|
|
||||||
}{
|
|
||||||
{"Disposition: S/Mime", DispositionSMime, `attachment; filename="smime.p7s"`},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if tt.d.String() != tt.want {
|
|
||||||
t.Errorf("wrong string for Disposition returned. Expected: %s, got: %s",
|
|
||||||
tt.want, tt.d.String())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -269,9 +269,6 @@ func (mw *msgWriter) writePart(part *Part, charset Charset) {
|
||||||
if part.description != "" {
|
if part.description != "" {
|
||||||
mimeHeader.Add(string(HeaderContentDescription), part.description)
|
mimeHeader.Add(string(HeaderContentDescription), part.description)
|
||||||
}
|
}
|
||||||
if part.disposition != "" {
|
|
||||||
mimeHeader.Add(string(HeaderContentDisposition), part.disposition.String())
|
|
||||||
}
|
|
||||||
mimeHeader.Add(string(HeaderContentType), contentType)
|
mimeHeader.Add(string(HeaderContentType), contentType)
|
||||||
mimeHeader.Add(string(HeaderContentTransferEnc), contentTransferEnc)
|
mimeHeader.Add(string(HeaderContentTransferEnc), contentTransferEnc)
|
||||||
mw.newPart(mimeHeader)
|
mw.newPart(mimeHeader)
|
||||||
|
|
20
part.go
20
part.go
|
@ -17,10 +17,10 @@ type Part struct {
|
||||||
contentType ContentType
|
contentType ContentType
|
||||||
charset Charset
|
charset Charset
|
||||||
description string
|
description string
|
||||||
disposition Disposition
|
|
||||||
encoding Encoding
|
encoding Encoding
|
||||||
isDeleted bool
|
isDeleted bool
|
||||||
writeFunc func(io.Writer) (int64, error)
|
writeFunc func(io.Writer) (int64, error)
|
||||||
|
smime bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContent executes the WriteFunc of the Part and returns the content as byte slice
|
// GetContent executes the WriteFunc of the Part and returns the content as byte slice
|
||||||
|
@ -57,9 +57,9 @@ func (p *Part) GetDescription() string {
|
||||||
return p.description
|
return p.description
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDisposition returns the currently set Content-Disposition of the Part
|
// IsSMimeSigned returns true if the Part should be singed with S/MIME
|
||||||
func (p *Part) GetDisposition() Disposition {
|
func (p *Part) IsSMimeSigned() bool {
|
||||||
return p.disposition
|
return p.smime
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContent overrides the content of the Part with the given string
|
// SetContent overrides the content of the Part with the given string
|
||||||
|
@ -88,9 +88,9 @@ func (p *Part) SetDescription(description string) {
|
||||||
p.description = description
|
p.description = description
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDisposition overrides the Content-Disposition of the Part
|
// SetIsSMimeSigned sets the flag for signing the Part with S/MIME
|
||||||
func (p *Part) SetDisposition(disposition Disposition) {
|
func (p *Part) SetIsSMimeSigned(smime bool) {
|
||||||
p.disposition = disposition
|
p.smime = smime
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetWriteFunc overrides the WriteFunc of the Part
|
// SetWriteFunc overrides the WriteFunc of the Part
|
||||||
|
@ -125,9 +125,9 @@ func WithPartContentDescription(description string) PartOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithContentDisposition overrides the default Part Content-Disposition
|
// WithSMimeSinging overrides the flag for signing the Part with S/MIME
|
||||||
func WithContentDisposition(disposition Disposition) PartOption {
|
func WithSMimeSinging() PartOption {
|
||||||
return func(p *Part) {
|
return func(p *Part) {
|
||||||
p.disposition = disposition
|
p.smime = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
90
part_test.go
90
part_test.go
|
@ -102,32 +102,21 @@ func TestPart_WithPartContentDescription(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestPart_withContentDisposition tests the WithContentDisposition method
|
// TestPart_WithSMimeSinging tests the WithSMimeSinging method
|
||||||
func TestPart_withContentDisposition(t *testing.T) {
|
func TestPart_WithSMimeSinging(t *testing.T) {
|
||||||
tests := []struct {
|
m := NewMsg()
|
||||||
name string
|
part := m.newPart(TypeTextPlain, WithSMimeSinging())
|
||||||
disposition Disposition
|
if part == nil {
|
||||||
}{
|
t.Errorf("newPart() WithSMimeSinging() failed: no part returned")
|
||||||
{"Part disposition: test", "test"},
|
return
|
||||||
{"Part disposition: empty", ""},
|
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
if part.smime != true {
|
||||||
m := NewMsg()
|
t.Errorf("newPart() WithSMimeSinging() failed: expected: %v, got: %v", true, part.smime)
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
}
|
||||||
part := m.newPart(TypeTextPlain, WithContentDisposition(tt.disposition), nil)
|
part.smime = true
|
||||||
if part == nil {
|
part.SetIsSMimeSigned(false)
|
||||||
t.Errorf("newPart() WithPartContentDescription() failed: no part returned")
|
if part.smime != false {
|
||||||
return
|
t.Errorf("newPart() SetIsSMimeSigned() failed: expected: %v, got: %v", false, part.smime)
|
||||||
}
|
|
||||||
if part.disposition != tt.disposition {
|
|
||||||
t.Errorf("newPart() WithContentDisposition() failed: expected: %s, got: %s", tt.disposition, part.description)
|
|
||||||
}
|
|
||||||
part.disposition = ""
|
|
||||||
part.SetDisposition(tt.disposition)
|
|
||||||
if part.disposition != tt.disposition {
|
|
||||||
t.Errorf("newPart() SetDisposition() failed: expected: %s, got: %s", tt.disposition, part.description)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +263,32 @@ func TestPart_GetContentBroken(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPart_IsSMimeSigned tests Part.IsSMimeSigned
|
||||||
|
func TestPart_IsSMimeSigned(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"smime:", true},
|
||||||
|
{"smime:", false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
m := NewMsg()
|
||||||
|
pl, err := getPartList(m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pl[0].SetIsSMimeSigned(tt.want)
|
||||||
|
smime := pl[0].IsSMimeSigned()
|
||||||
|
if smime != tt.want {
|
||||||
|
t.Errorf("SetContentType failed. Got: %v, expected: %v", smime, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestPart_SetWriteFunc tests Part.SetWriteFunc
|
// TestPart_SetWriteFunc tests Part.SetWriteFunc
|
||||||
func TestPart_SetWriteFunc(t *testing.T) {
|
func TestPart_SetWriteFunc(t *testing.T) {
|
||||||
c := "This is a test with ümläutß"
|
c := "This is a test with ümläutß"
|
||||||
|
@ -352,31 +367,6 @@ func TestPart_SetDescription(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestPart_SetDisposition tests Part.SetDisposition
|
|
||||||
func TestPart_SetDisposition(t *testing.T) {
|
|
||||||
c := "This is a test"
|
|
||||||
d := Disposition("test-disposition")
|
|
||||||
m := NewMsg()
|
|
||||||
m.SetBodyString(TypeTextPlain, c)
|
|
||||||
pl, err := getPartList(m)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("failed: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pd := pl[0].GetDisposition()
|
|
||||||
if pd != "" {
|
|
||||||
t.Errorf("Part.GetDisposition failed. Expected empty description but got: %s", pd)
|
|
||||||
}
|
|
||||||
pl[0].SetDisposition(d)
|
|
||||||
if pl[0].disposition != d {
|
|
||||||
t.Errorf("Part.SetDisposition failed. Expected description to be: %s, got: %s", d, pd)
|
|
||||||
}
|
|
||||||
pd = pl[0].GetDisposition()
|
|
||||||
if pd != d {
|
|
||||||
t.Errorf("Part.GetDisposition failed. Expected: %s, got: %s", d, pd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPart_Delete tests Part.Delete
|
// TestPart_Delete tests Part.Delete
|
||||||
func TestPart_Delete(t *testing.T) {
|
func TestPart_Delete(t *testing.T) {
|
||||||
c := "This is a test with ümläutß"
|
c := "This is a test with ümläutß"
|
||||||
|
|
Loading…
Reference in a new issue