From fef42081b3e5bda85b9d6f689ca9460661f30db8 Mon Sep 17 00:00:00 2001 From: Chun-Hung Tseng Date: Thu, 29 Jun 2023 22:10:03 +0200 Subject: [PATCH] Make AppVersion a configuration option Refactor out NewClientWithRefresh in the login function --- README.md | 2 +- common/config.go | 12 ++++++++---- common/proton_manager.go | 23 +++++------------------ common/user.go | 22 ++++------------------ file.go | 8 +++++--- 5 files changed, 23 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index e3de74a..5bf037f 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ V2 will bring in optimizations and enhancements, such as optimizing uploading an - [x] Remove delete all's hardcoded string - [x] Point to the right proton-go-api branch - [x] Run `go get github.com/henrybear327/go-proton-api@dev` to update go mod +- [x] Pass in AppVersion as a config option ### Known limitations @@ -102,7 +103,6 @@ V2 will bring in optimizations and enhancements, such as optimizing uploading an - [ ] Remove e.g. proton.link related exposures in the function signature (this library should abstract them all) - [ ] Documentation - [ ] Go through Drive iOS source code and check the logic control flow -- [ ] Use proper AppVersion (we need to be friendly to the Proton servers) - [ ] Figure out the bottleneck by doing some profiling - [ ] Proper error handling by looking at the return code instead of the error string - [ ] Duplicated folder name handling: 422: A file or folder with that name already exists (Code=2500, Status=422) diff --git a/common/config.go b/common/config.go index 5891c1f..ad49fe9 100644 --- a/common/config.go +++ b/common/config.go @@ -3,12 +3,14 @@ package common import "os" type Config struct { + /* Constants */ + AppVersion string + /* Login */ FirstLoginCredential *FirstLoginCredentialData ReusableCredential *ReusableCredentialData UseReusableLogin bool CredentialCacheFile string // If CredentialCacheFile is empty, no credential will be logged - RefreshAccessToken bool /* Setting */ DestructiveIntegrationTest bool // CAUTION: the integration test requires a clean proton drive @@ -33,7 +35,8 @@ type ReusableCredentialData struct { func NewConfigWithDefaultValues() *Config { return &Config{ - // login + AppVersion: "", + FirstLoginCredential: &FirstLoginCredentialData{ Username: "", Password: "", @@ -47,7 +50,6 @@ func NewConfigWithDefaultValues() *Config { }, UseReusableLogin: false, CredentialCacheFile: "", - RefreshAccessToken: false, DestructiveIntegrationTest: false, EmptyTrashAfterIntegrationTest: false, @@ -57,6 +59,7 @@ func NewConfigWithDefaultValues() *Config { } func NewConfigForIntegrationTests() *Config { + appVersion := os.Getenv("PROTON_API_BRIDGE_APP_VERSION") username := os.Getenv("PROTON_API_BRIDGE_TEST_USERNAME") password := os.Getenv("PROTON_API_BRIDGE_TEST_PASSWORD") twoFA := os.Getenv("PROTON_API_BRIDGE_TEST_TWOFA") @@ -73,6 +76,8 @@ func NewConfigForIntegrationTests() *Config { saltedKeyPass := os.Getenv("PROTON_API_BRIDGE_TEST_SALTEDKEYPASS") return &Config{ + AppVersion: appVersion, + FirstLoginCredential: &FirstLoginCredentialData{ Username: username, Password: password, @@ -86,7 +91,6 @@ func NewConfigForIntegrationTests() *Config { }, UseReusableLogin: useReusableLogin, CredentialCacheFile: ".credential", - RefreshAccessToken: false, DestructiveIntegrationTest: true, EmptyTrashAfterIntegrationTest: true, diff --git a/common/proton_manager.go b/common/proton_manager.go index 0477c0b..400b04a 100644 --- a/common/proton_manager.go +++ b/common/proton_manager.go @@ -4,25 +4,12 @@ import ( "github.com/henrybear327/go-proton-api" ) -// TODO: use proper appname and version -func AppVersion() string { - // return "web-drive@5.0.13.8" - return "ios-drive@1.14.0" -} - -func defaultAPIOptions() []proton.Option { - return []proton.Option{ - proton.WithAppVersion(AppVersion()), +func getProtonManager(appVersion string) *proton.Manager { + /* Notes on API calls: if the app version is not specified, the api calls will be rejected. */ + options := []proton.Option{ + proton.WithAppVersion(appVersion), } -} - -func getProtonManager() *proton.Manager { - /* - Notes on API calls - - If the app version is not specified, the api calls will be rejected. - */ - m := proton.New(defaultAPIOptions()...) + m := proton.New(options...) return m } diff --git a/common/user.go b/common/user.go index 71cfda4..3273c1e 100644 --- a/common/user.go +++ b/common/user.go @@ -48,28 +48,14 @@ func Login(ctx context.Context, config *Config) (*proton.Manager, *proton.Client var addr []proton.Address // get manager - m := getProtonManager() + m := getProtonManager(config.AppVersion) if config.UseReusableLogin { - /* - Using NewClientWithRefresh so the credential can last longer, - as each run of the program will trigger a access token refresh - */ - var err error - if config.RefreshAccessToken { - c, auth, err = m.NewClientWithRefresh(ctx, config.ReusableCredential.UID, config.ReusableCredential.RefreshToken) - if err != nil { - return nil, nil, nil, nil, nil, err - } + c = m.NewClient(config.ReusableCredential.UID, config.ReusableCredential.AccessToken, config.ReusableCredential.RefreshToken) - config.ReusableCredential.UID = auth.UID - config.ReusableCredential.AccessToken = auth.AccessToken - config.ReusableCredential.RefreshToken = auth.RefreshToken - } else { - c = m.NewClient(config.ReusableCredential.UID, config.ReusableCredential.AccessToken, config.ReusableCredential.RefreshToken) - } + // TODO: register auth/deauth handler - err = cacheCredentialToFile(config) + err := cacheCredentialToFile(config) if err != nil { return nil, nil, nil, nil, nil, err } diff --git a/file.go b/file.go index 68c16a6..ee9e908 100644 --- a/file.go +++ b/file.go @@ -240,6 +240,7 @@ func (protonDrive *ProtonDrive) uploadAndCollectBlockData(ctx context.Context, n // FIXME: handle partial upload (failed midway) // FIXME: get block size from the server config instead of hardcoding it + // FIXME: improve memory management blockSize := UPLOAD_BLOCK_SIZE type PendingUploadBlocks struct { blockUploadInfo proton.BlockUploadInfo @@ -248,11 +249,12 @@ func (protonDrive *ProtonDrive) uploadAndCollectBlockData(ctx context.Context, n blocks := make([]PendingUploadBlocks, 0) manifestSignatureData := make([]byte, 0) - for i := 0; i*blockSize < len(fileContent); i++ { + fileLength := len(fileContent) + for i := 0; i*blockSize < fileLength; i++ { // encrypt data upperBound := (i + 1) * blockSize - if upperBound > len(fileContent) { - upperBound = len(fileContent) + if upperBound > fileLength { + upperBound = fileLength } data := fileContent[i*blockSize : upperBound]