cleanup: Remove unused packages

create-reload-action
Lukasz Janyst 4 years ago
parent 3182a3296b
commit 92da6ca550
No known key found for this signature in database
GPG Key ID: 32DE641041F17A9A
  1. 19
      pkg/algo/algo.go
  2. 47
      pkg/algo/sets.go
  3. 71
      pkg/algo/sets_test.go
  4. 38
      pkg/constants/constants.go
  5. 28
      pkg/constants/update_default.go
  6. 28
      pkg/constants/update_qa.go
  7. 46
      pkg/dialer/dial_client.go
  8. 75
      pkg/mobileconfig/config.go
  9. 153
      pkg/mobileconfig/template.go
  10. 43
      pkg/signature/signature.go
  11. 85
      pkg/sum/sum.go
  12. 112
      pkg/sum/sum_test.go
  13. 104
      pkg/tar/tar.go
  14. 215
      pkg/transfer/mocks/mocks.go

@ -1,19 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// Package algo provides some algorithm utils.
package algo

@ -1,47 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package algo
import "reflect"
// SetIntersection complexity: O(n^2), could be better but this is simple enough.
func SetIntersection(a, b interface{}, eq func(a, b interface{}) bool) []interface{} {
set := make([]interface{}, 0)
av := reflect.ValueOf(a)
for i := 0; i < av.Len(); i++ {
el := av.Index(i).Interface()
if contains(b, el, eq) {
set = append(set, el)
}
}
return set
}
func contains(a, e interface{}, eq func(a, b interface{}) bool) bool {
v := reflect.ValueOf(a)
for i := 0; i < v.Len(); i++ {
if eq(v.Index(i).Interface(), e) {
return true
}
}
return false
}

@ -1,71 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package algo
import (
"testing"
"github.com/google/go-cmp/cmp"
)
type T struct {
k, v int
}
func TestSetIntersection(t *testing.T) {
keysAreEqual := func(a, b interface{}) bool {
return a.(T).k == b.(T).k
}
type args struct {
a interface{}
b interface{}
eq func(a, b interface{}) bool
}
tests := []struct {
name string
args args
want interface{}
}{
{
name: "integer sets",
args: args{a: []int{1, 2, 3}, b: []int{3, 4, 5}, eq: func(a, b interface{}) bool { return a == b }},
want: []int{3},
},
{
name: "string sets",
args: args{a: []string{"1", "2", "3"}, b: []string{"3", "4", "5"}, eq: func(a, b interface{}) bool { return a == b }},
want: []string{"3"},
},
{
name: "custom comp, only compare on keys, prefer first set if keys are the same",
args: args{a: []T{{k: 1, v: 1}, {k: 2, v: 2}}, b: []T{{k: 2, v: 1234}, {k: 3, v: 3}}, eq: keysAreEqual},
want: []T{{k: 2, v: 2}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// using cmp.Equal because it handles the interfaces correctly; testify/assert doesn't
// treat these as equal because their types are different ([]interface vs []int)
if got := SetIntersection(tt.args.a, tt.args.b, tt.args.eq); cmp.Equal(got, tt.want) {
t.Errorf("SetIntersection() = %v, want %v", got, tt.want)
}
})
}
}

@ -1,38 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// Package constants contains variables that are set via ldflags during build.
package constants
import "fmt"
const VendorName = "protonmail"
// nolint[gochecknoglobals]
var (
// Version of the build.
Version = "1000.1000.1000+git"
// Revision is current hash of the build.
Revision = "bf2a7aaf0f"
// BuildTime stamp of the build.
BuildTime = "2022-01-01T17:20:35+0100"
// BuildVersion is derived from LongVersion and BuildTime.
BuildVersion = fmt.Sprintf("%v (%v) %v", Version, Revision, BuildTime)
)

@ -1,28 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// +build !build_qa
package constants
import "time"
// nolint[gochecknoglobals]
var (
// UpdateCheckInterval defines how often we check for new version
UpdateCheckInterval = time.Hour //nolint[gochecknoglobals]
)

@ -1,28 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// +build build_qa
package constants
import "time"
// nolint[gochecknoglobals]
var (
// UpdateCheckInterval defines how often we check for new version
UpdateCheckInterval = time.Duration(5 * time.Minute)
)

@ -1,46 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package dialer
import (
"net"
"net/http"
"time"
)
const (
// ClientTimeout is the timeout for the whole request (from dial to
// receiving the response body). It should be large enough to download
// even the largest attachments or the new binary of the Bridge, but
// should be hit if the server hangs (default is infinite which is bad).
clientTimeout = 30 * time.Minute
dialTimeout = 3 * time.Second
)
// DialTimeoutClient creates client with overridden dialTimeout.
func DialTimeoutClient() *http.Client {
transport := &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
return net.DialTimeout(network, addr, dialTimeout)
},
}
return &http.Client{
Timeout: clientTimeout,
Transport: transport,
}
}

@ -1,75 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package mobileconfig
import (
"io"
"text/template"
"github.com/google/uuid"
)
// Config represents an Apple mobileconfig file.
type Config struct {
EmailAddress string
DisplayName string
Identifier string
Organization string
AccountDescription string
IMAP *IMAP
SMTP *SMTP
Description string
ContentUUID string
UUID string
}
type IMAP struct {
Hostname string
Port int
TLS bool
Username string
Password string
}
type SMTP struct {
Hostname string
Port int
TLS bool
// Leave Username blank to do not use SMTP authentication.
Username string
// Leave Password blank to use IMAP credentials.
Password string
}
func (c *Config) WriteOut(w io.Writer) error {
if c.ContentUUID == "" {
uuid := uuid.New()
c.ContentUUID = uuid.String()
}
if c.UUID == "" {
uuid := uuid.New()
c.UUID = uuid.String()
}
return template.Must(template.New("mobileconfig").Parse(mailTemplate)).Execute(w, c)
}

@ -1,153 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package mobileconfig
const mailTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
{{- if .AccountDescription}}
<key>EmailAccountDescription</key>
<string>{{.AccountDescription}}</string>
{{- end}}
{{- if .IMAP}}
<key>EmailAccountType</key>
<string>EmailTypeIMAP</string>
<key>EmailAddress</key>
<string>{{.EmailAddress}}</string>
<key>IncomingMailServerAuthentication</key>
<string>EmailAuthPassword</string>
<key>IncomingMailServerHostName</key>
<string>{{.IMAP.Hostname}}</string>
<key>IncomingMailServerPortNumber</key>
<integer>{{.IMAP.Port}}</integer>
<key>IncomingMailServerUseSSL</key>
{{- if .IMAP.TLS}}
<true/>
{{- else}}
<false/>
{{- end}}
<key>IncomingMailServerUsername</key>
<string>{{.IMAP.Username}}</string>
<key>IncomingPassword</key>
<string>{{.IMAP.Password}}</string>
{{- end}}
{{ if .SMTP}}
<key>OutgoingMailServerAuthentication</key>
<string>{{if .SMTP.Username}}EmailAuthPassword{{else}}EmailAuthNone{{end}}</string>
<key>OutgoingMailServerHostName</key>
<string>{{.SMTP.Hostname}}</string>
<key>OutgoingMailServerPortNumber</key>
<integer>{{.SMTP.Port}}</integer>
<key>OutgoingMailServerUseSSL</key>
{{- if .SMTP.TLS}}
<true/>
{{- else}}
<false/>
{{- end}}
{{- if .SMTP.Username}}
<key>OutgoingMailServerUsername</key>
<string>{{.SMTP.Username}}</string>
{{- end}}
{{- if .SMTP.Password}}
<key>OutgoingPassword</key>
<string>{{.SMTP.Password}}</string>
{{- else}}
<key>OutgoingPasswordSameAsIncomingPassword</key>
<true/>
{{- end}}
{{end}}
<key>PayloadDescription</key>
<string>Configures email account.</string>
<key>PayloadDisplayName</key>
<string>{{.DisplayName}}</string>
<key>PayloadIdentifier</key>
<string>{{.Identifier}}</string>
{{- if .Organization}}
<key>PayloadOrganization</key>
<string>{{.Organization}}</string>
{{- end}}
<key>PayloadType</key>
<string>com.apple.mail.managed</string>
<key>PayloadUUID</key>
<string>{{.ContentUUID}}</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PreventAppSheet</key>
<false/>
<key>PreventMove</key>
<false/>
<key>SMIMEEnabled</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>{{if .Description}}{{.Description}}{{else}}Install this profile to auto configure email account for {{.EmailAddress}}.{{- end}}</string>
<key>PayloadDisplayName</key>
<string>{{.DisplayName}}</string>
<key>PayloadIdentifier</key>
<string>{{.Identifier}}</string>
{{- if .Organization}}
<key>PayloadOrganization</key>
<string>{{.Organization}}</string>
{{- end}}
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>{{.UUID}}</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>`

@ -1,43 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// Package signature implements functions to verify files by their detached signatures.
package signature
import (
"github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/pkg/errors"
)
// Verify verifies the given file by its signature using the given armored public key.
func Verify(fileBytes, sigBytes []byte, pubKey string) error {
key, err := crypto.NewKeyFromArmored(pubKey)
if err != nil {
return errors.Wrap(err, "failed to load key")
}
kr, err := crypto.NewKeyRing(key)
if err != nil {
return errors.Wrap(err, "failed to create keyring")
}
return kr.VerifyDetached(
crypto.NewPlainMessage(fileBytes),
crypto.NewPGPSignature(sigBytes),
crypto.GetUnixTime(),
)
}

@ -1,85 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package sum
import (
"crypto/sha512"
"encoding/base64"
"io"
"os"
"path/filepath"
"github.com/sirupsen/logrus"
)
// RecursiveSum computes the sha512 sum of all files in the root directory and descendents.
// If a skipFile is provided (e.g. the path of a checksum file relative to
// rootDir), it (and its signature) is ignored.
func RecursiveSum(rootDir, skipFileName string) ([]byte, error) {
hash := sha512.New()
// In windows filepath accepts both delimiters `\` and `/`. In order to
// to properly skip file we have to choose one native delimiter.
rootDir = filepath.FromSlash(rootDir)
skipFile := filepath.Join(rootDir, skipFileName)
skipFileSig := skipFile + ".sig"
if err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
log := logrus.
WithField("path", path).
WithField("sum", base64.StdEncoding.EncodeToString(hash.Sum([]byte{})))
log.Debug("Next file")
if err != nil {
log.WithError(err).Error("Walk failed")
return err
}
if info.IsDir() {
log.Debug("Skip dir")
return nil
}
// The hashfile itself isn't included in the hash.
if path == skipFile || path == skipFileSig {
log.Debug("Skip file")
return nil
}
rel, err := filepath.Rel(rootDir, path)
if err != nil {
log.WithError(err).Error("Failed to find relative path")
return err
}
if _, err := hash.Write([]byte(rel)); err != nil {
log.WithError(err).Error("Failed to write path")
return err
}
f, err := os.Open(path) // nolint[gosec]
if err != nil {
log.WithError(err).Error("Failed to open file")
return err
}
if _, err := io.Copy(hash, f); err != nil {
log.WithError(err).Error("Copy to hash failed")
return err
}
return f.Close()
}); err != nil {
return nil, err
}
return hash.Sum([]byte{}), nil
}

@ -1,112 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package sum
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
)
func TestRecursiveSum(t *testing.T) {
tempDir, err := ioutil.TempDir("", "verify-test")
require.NoError(t, err)
createFiles(t, tempDir,
filepath.Join("a", "1"),
filepath.Join("a", "2"),
filepath.Join("b", "3"),
filepath.Join("b", "4"),
filepath.Join("b", "c", "5"),
filepath.Join("b", "c", "6"),
)
sumOriginal := sum(t, tempDir)
// Renaming files should produce a different checksum.
require.NoError(t, os.Rename(filepath.Join(tempDir, "a", "1"), filepath.Join(tempDir, "a", "11")))
sumRenamed := sum(t, tempDir)
require.NotEqual(t, sumOriginal, sumRenamed)
// Reverting to the original name should produce the same checksum again.
require.NoError(t, os.Rename(filepath.Join(tempDir, "a", "11"), filepath.Join(tempDir, "a", "1")))
require.Equal(t, sumOriginal, sum(t, tempDir))
// Moving files should produce a different checksum.
require.NoError(t, os.Rename(filepath.Join(tempDir, "a", "1"), filepath.Join(tempDir, "1")))
sumMoved := sum(t, tempDir)
require.NotEqual(t, sumOriginal, sumMoved)
// Moving files back to their original location should produce the same checksum again.
require.NoError(t, os.Rename(filepath.Join(tempDir, "1"), filepath.Join(tempDir, "a", "1")))
require.Equal(t, sumOriginal, sum(t, tempDir))
// Changing file data should produce a different checksum.
originalData := modifyFile(t, filepath.Join(tempDir, "a", "1"), []byte("something"))
require.NotEqual(t, sumOriginal, sum(t, tempDir))
// Reverting file data should produce the original checksum.
modifyFile(t, filepath.Join(tempDir, "a", "1"), originalData)
require.Equal(t, sumOriginal, sum(t, tempDir))
}
func createFiles(t *testing.T, root string, paths ...string) {
for _, path := range paths {
makeFile(t, filepath.Join(root, path))
}
}
func makeFile(t *testing.T, path string) {
require.NoError(t, os.MkdirAll(filepath.Dir(path), 0700))
f, err := os.Create(path)
require.NoError(t, err)
_, err = f.WriteString(path)
require.NoError(t, err)
require.NoError(t, f.Close())
}
func sum(t *testing.T, path string) []byte {
sum, err := RecursiveSum(path, "")
require.NoError(t, err)
return sum
}
func modifyFile(t *testing.T, path string, data []byte) []byte {
r, err := os.Open(path)
require.NoError(t, err)
b, err := ioutil.ReadAll(r)
require.NoError(t, err)
require.NoError(t, r.Close())
f, err := os.Create(path)
require.NoError(t, err)
_, err = f.Write(data)
require.NoError(t, err)
require.NoError(t, f.Close())
return b
}

@ -1,104 +0,0 @@
// Copyright (c) 2022 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
package tar
import (
"archive/tar"
"errors"
"io"
"os"
"path/filepath"
"runtime"
"github.com/sirupsen/logrus"
)
// maxFileSize limit tre single file size after decopression is not larger than 1GB.
const maxFileSize = int64(1 * 1024 * 1024 * 1024) // 1 GB
// ErrFileTooLarge returned when decompressed file is too large.
var ErrFileTooLarge = errors.New("trying to decompress file larger than 1GB")
type limitReader struct {
r io.Reader
n int64
}
// Read returns error if limit was exceeded. Inspired by io.LimitReader.Read
// implementation.
func (lr *limitReader) Read(p []byte) (n int, err error) {
if lr.n <= 0 {
return 0, ErrFileTooLarge
}
if int64(len(p)) > lr.n {
p = p[0:lr.n]
}
n, err = lr.r.Read(p)
lr.n -= int64(n)
return
}
// UntarToDir decopmress and unarchive the files into directory.
func UntarToDir(r io.Reader, dir string) error {
tr := tar.NewReader(r)
for {
header, err := tr.Next()
if err == io.EOF {
return nil
}
if err != nil {
return err
}
if header == nil {
continue
}
target := filepath.Join(dir, filepath.Clean(header.Name)) // gosec G305
switch {
case header.Typeflag == tar.TypeSymlink:
if err := os.Symlink(header.Linkname, target); err != nil {
return err
}
case header.FileInfo().IsDir():
if err := os.MkdirAll(target, header.FileInfo().Mode()); err != nil {
return err
}
default:
f, err := os.Create(target)
if err != nil {
return err
}
lr := &limitReader{r: tr, n: maxFileSize} // gosec G110
if _, err := io.Copy(f, lr); err != nil {
return err
}
if runtime.GOOS != "windows" {
if err := f.Chmod(header.FileInfo().Mode()); err != nil {
return err
}
}
if err := f.Close(); err != nil {
logrus.WithError(err).Error("Failed to close file")
}
}
}
}

@ -1,215 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ljanyst/peroxide/pkg/transfer (interfaces: PanicHandler,IMAPClientProvider)
// Package mocks is a generated GoMock package.
package mocks
import (
reflect "reflect"
imap "github.com/emersion/go-imap"
sasl "github.com/emersion/go-sasl"
gomock "github.com/golang/mock/gomock"
)
// MockPanicHandler is a mock of PanicHandler interface.
type MockPanicHandler struct {
ctrl *gomock.Controller
recorder *MockPanicHandlerMockRecorder
}
// MockPanicHandlerMockRecorder is the mock recorder for MockPanicHandler.
type MockPanicHandlerMockRecorder struct {
mock *MockPanicHandler
}
// NewMockPanicHandler creates a new mock instance.
func NewMockPanicHandler(ctrl *gomock.Controller) *MockPanicHandler {
mock := &MockPanicHandler{ctrl: ctrl}
mock.recorder = &MockPanicHandlerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockPanicHandler) EXPECT() *MockPanicHandlerMockRecorder {
return m.recorder
}
// HandlePanic mocks base method.
func (m *MockPanicHandler) HandlePanic() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "HandlePanic")
}
// HandlePanic indicates an expected call of HandlePanic.
func (mr *MockPanicHandlerMockRecorder) HandlePanic() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandlePanic", reflect.TypeOf((*MockPanicHandler)(nil).HandlePanic))
}
// MockIMAPClientProvider is a mock of IMAPClientProvider interface.
type MockIMAPClientProvider struct {
ctrl *gomock.Controller
recorder *MockIMAPClientProviderMockRecorder
}
// MockIMAPClientProviderMockRecorder is the mock recorder for MockIMAPClientProvider.
type MockIMAPClientProviderMockRecorder struct {
mock *MockIMAPClientProvider
}
// NewMockIMAPClientProvider creates a new mock instance.
func NewMockIMAPClientProvider(ctrl *gomock.Controller) *MockIMAPClientProvider {
mock := &MockIMAPClientProvider{ctrl: ctrl}
mock.recorder = &MockIMAPClientProviderMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockIMAPClientProvider) EXPECT() *MockIMAPClientProviderMockRecorder {
return m.recorder
}
// Authenticate mocks base method.
func (m *MockIMAPClientProvider) Authenticate(arg0 sasl.Client) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Authenticate", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Authenticate indicates an expected call of Authenticate.
func (mr *MockIMAPClientProviderMockRecorder) Authenticate(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Authenticate", reflect.TypeOf((*MockIMAPClientProvider)(nil).Authenticate), arg0)
}
// Capability mocks base method.
func (m *MockIMAPClientProvider) Capability() (map[string]bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Capability")
ret0, _ := ret[0].(map[string]bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Capability indicates an expected call of Capability.
func (mr *MockIMAPClientProviderMockRecorder) Capability() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Capability", reflect.TypeOf((*MockIMAPClientProvider)(nil).Capability))
}
// Fetch mocks base method.
func (m *MockIMAPClientProvider) Fetch(arg0 *imap.SeqSet, arg1 []imap.FetchItem, arg2 chan *imap.Message) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Fetch", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// Fetch indicates an expected call of Fetch.
func (mr *MockIMAPClientProviderMockRecorder) Fetch(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Fetch", reflect.TypeOf((*MockIMAPClientProvider)(nil).Fetch), arg0, arg1, arg2)
}
// List mocks base method.
func (m *MockIMAPClientProvider) List(arg0, arg1 string, arg2 chan *imap.MailboxInfo) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "List", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// List indicates an expected call of List.
func (mr *MockIMAPClientProviderMockRecorder) List(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIMAPClientProvider)(nil).List), arg0, arg1, arg2)
}
// Login mocks base method.
func (m *MockIMAPClientProvider) Login(arg0, arg1 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Login", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// Login indicates an expected call of Login.
func (mr *MockIMAPClientProviderMockRecorder) Login(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Login", reflect.TypeOf((*MockIMAPClientProvider)(nil).Login), arg0, arg1)
}
// Select mocks base method.
func (m *MockIMAPClientProvider) Select(arg0 string, arg1 bool) (*imap.MailboxStatus, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Select", arg0, arg1)
ret0, _ := ret[0].(*imap.MailboxStatus)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Select indicates an expected call of Select.
func (mr *MockIMAPClientProviderMockRecorder) Select(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Select", reflect.TypeOf((*MockIMAPClientProvider)(nil).Select), arg0, arg1)
}
// State mocks base method.
func (m *MockIMAPClientProvider) State() imap.ConnState {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "State")
ret0, _ := ret[0].(imap.ConnState)
return ret0
}
// State indicates an expected call of State.
func (mr *MockIMAPClientProviderMockRecorder) State() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "State", reflect.TypeOf((*MockIMAPClientProvider)(nil).State))
}
// Support mocks base method.
func (m *MockIMAPClientProvider) Support(arg0 string) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Support", arg0)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Support indicates an expected call of Support.
func (mr *MockIMAPClientProviderMockRecorder) Support(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Support", reflect.TypeOf((*MockIMAPClientProvider)(nil).Support), arg0)
}
// SupportAuth mocks base method.
func (m *MockIMAPClientProvider) SupportAuth(arg0 string) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SupportAuth", arg0)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SupportAuth indicates an expected call of SupportAuth.
func (mr *MockIMAPClientProviderMockRecorder) SupportAuth(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SupportAuth", reflect.TypeOf((*MockIMAPClientProvider)(nil).SupportAuth), arg0)
}
// UidFetch mocks base method.
func (m *MockIMAPClientProvider) UidFetch(arg0 *imap.SeqSet, arg1 []imap.FetchItem, arg2 chan *imap.Message) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UidFetch", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// UidFetch indicates an expected call of UidFetch.
func (mr *MockIMAPClientProviderMockRecorder) UidFetch(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UidFetch", reflect.TypeOf((*MockIMAPClientProvider)(nil).UidFetch), arg0, arg1, arg2)
}
Loading…
Cancel
Save