Skip to content

Commit

Permalink
rework unhandled errors
Browse files Browse the repository at this point in the history
  • Loading branch information
lostb1t committed Sep 23, 2024
1 parent 279504a commit 73f630b
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 36 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Rclone *("rsync for cloud storage")* is a command-line program to sync files and
* Huawei Cloud Object Storage Service(OBS) [:page_facing_up:](https://rclone.org/s3/#huawei-obs)
* ImageKit [:page_facing_up:](https://rclone.org/imagekit/)
* Internet Archive [:page_facing_up:](https://rclone.org/internetarchive/)
* iCloud Drive [:page_facing_up:](https://rclone.org/iclouddrive/)
* Jottacloud [:page_facing_up:](https://rclone.org/jottacloud/)
* IBM COS S3 [:page_facing_up:](https://rclone.org/s3/#ibm-cos-s3)
* IONOS Cloud [:page_facing_up:](https://rclone.org/s3/#ionos)
Expand Down
6 changes: 5 additions & 1 deletion backend/icloud/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ func New(appleID, password, trustToken string, clientID string, cookies []*http.

// DriveService returns the DriveService instance associated with the Client.
func (c *Client) DriveService() (*DriveService, error) {
var err error
if c.drive == nil {
c.drive, _ = NewDriveService(c)
c.drive, err = NewDriveService(c)
if err != nil {
return nil, err
}
}
return c.drive, nil
}
Expand Down
65 changes: 50 additions & 15 deletions backend/icloud/api/drive.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (d *DriveService) GetItemByDriveID(ctx context.Context, id string, includeC

// GetItemsByDriveID retrieves DriveItems by their Drive IDs.
func (d *DriveService) GetItemsByDriveID(ctx context.Context, ids []string, includeChildren bool) ([]*DriveItem, *http.Response, error) {
var err error
_items := []map[string]any{}
for _, id := range ids {
_items = append(_items, map[string]any{
Expand All @@ -62,11 +63,17 @@ func (d *DriveService) GetItemsByDriveID(ctx context.Context, ids []string, incl
values := []map[string]any{{
"items": _items,
}}
body, _ = IntoReader(values)
body, err = IntoReader(values)
if err != nil {
return nil, nil, err
}
path = "/retrieveItemDetails"
} else {
values := _items
body, _ = IntoReader(values)
body, err = IntoReader(values)
if err != nil {
return nil, nil, err
}
path = "/retrieveItemDetailsInFolders"
}

Expand All @@ -90,9 +97,10 @@ func (d *DriveService) GetItemsByDriveID(ctx context.Context, ids []string, incl
func (d *DriveService) GetDocByPath(ctx context.Context, path string) (*Document, *http.Response, error) {
values := url.Values{}
values.Set("unified_format", "false")

body, _ := IntoReader(path)

body, err := IntoReader(path)
if err != nil {
return nil, nil, err
}
opts := rest.Opts{
Method: "POST",
Path: "/ws/" + defaultZone + "/list/lookup_by_path",
Expand All @@ -115,8 +123,10 @@ func (d *DriveService) GetItemByPath(ctx context.Context, path string) (*DriveIt
values := url.Values{}
values.Set("unified_format", "true")

body, _ := IntoReader(path)

body, err := IntoReader(path)
if err != nil {
return nil, nil, err
}
opts := rest.Opts{
Method: "POST",
Path: "/ws/" + defaultZone + "/list/lookup_by_path",
Expand Down Expand Up @@ -274,7 +284,11 @@ func (d *DriveService) MoveItemToTrashByID(ctx context.Context, drivewsid, etag
"clientId": drivewsid,
}}}

body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return nil, nil, err
}

opts := rest.Opts{
Method: "POST",
Path: "/moveItemsToTrash",
Expand Down Expand Up @@ -323,7 +337,11 @@ func (d *DriveService) CreateNewFolderByDriveID(ctx context.Context, drivewsid,
}},
}

body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return nil, nil, err
}

opts := rest.Opts{
Method: "POST",
Path: "/createFolders",
Expand Down Expand Up @@ -364,7 +382,11 @@ func (d *DriveService) RenameItemByDriveID(ctx context.Context, id, etag, name s
}},
}

body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return nil, nil, err
}

opts := rest.Opts{
Method: "POST",
Path: "/renameItems",
Expand Down Expand Up @@ -420,7 +442,11 @@ func (d *DriveService) MoveItemByDriveID(ctx context.Context, id, etag, dstID st
}},
}

body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return nil, nil, err
}

opts := rest.Opts{
Method: "POST",
Path: "/moveItems",
Expand Down Expand Up @@ -455,8 +481,10 @@ func (d *DriveService) CopyDocByItemID(ctx context.Context, itemID string) (*Dri
"info_to_update": map[string]any{},
}

body, _ := IntoReader(values)

body, err := IntoReader(values)
if err != nil {
return nil, nil, err
}
opts := rest.Opts{
Method: "POST",
Path: "/v1/item/copy/" + itemID,
Expand All @@ -482,7 +510,11 @@ func (d *DriveService) CreateUpload(ctx context.Context, size int64, name string
"size": strconv.FormatInt(size, 10),
"content_type": GetContentTypeForFile(name),
}
body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return nil, nil, err
}

opts := rest.Opts{
Method: "POST",
Path: "/ws/" + defaultZone + "/upload/web",
Expand Down Expand Up @@ -525,7 +557,10 @@ func (d *DriveService) Upload(ctx context.Context, in io.Reader, size int64, nam
// r: a pointer to the UpdateFileInfo struct containing the information for the file update.
// Returns a pointer to the DriveItem struct representing the updated file, the http.Response object, and an error if any.
func (d *DriveService) UpdateFile(ctx context.Context, r *UpdateFileInfo) (*DriveItem, *http.Response, error) {
body, _ := IntoReader(r)
body, err := IntoReader(r)
if err != nil {
return nil, nil, err
}
opts := rest.Opts{
Method: "POST",
Path: "/ws/" + defaultZone + "/update/documents",
Expand Down
28 changes: 18 additions & 10 deletions backend/icloud/api/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
Expand Down Expand Up @@ -30,10 +29,10 @@ type Session struct {
}

// String returns the session as a string
func (s *Session) String() string {
jsession, _ := json.Marshal(s)
return string(jsession)
}
// func (s *Session) String() string {
// jsession, _ := json.Marshal(s)
// return string(jsession)
// }

// Request makes a request
func (s *Session) Request(ctx context.Context, opts rest.Opts, request interface{}, response interface{}) (*http.Response, error) {
Expand Down Expand Up @@ -79,7 +78,10 @@ func (s *Session) SignIn(ctx context.Context, appleID, password string) error {
"rememberMe": true,
"trustTokens": trustTokens,
}
body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return err
}
opts := rest.Opts{
Method: "POST",
Path: "/signin",
Expand All @@ -91,7 +93,7 @@ func (s *Session) SignIn(ctx context.Context, appleID, password string) error {
Body: body,
}
opts.Parameters.Set("isRememberMeEnabled", "true")
_, err := s.Request(ctx, opts, nil, nil)
_, err = s.Request(ctx, opts, nil, nil)

return err

Expand All @@ -105,7 +107,10 @@ func (s *Session) AuthWithToken(ctx context.Context) error {
"extended_login": true,
"trustToken": s.TrustToken,
}
body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return err
}
opts := rest.Opts{
Method: "POST",
Path: "/accountLogin",
Expand All @@ -125,7 +130,10 @@ func (s *Session) AuthWithToken(ctx context.Context) error {
// Validate2FACode validates the 2FA code
func (s *Session) Validate2FACode(ctx context.Context, code string) error {
values := map[string]interface{}{"securityCode": map[string]string{"code": code}}
body, _ := IntoReader(values)
body, err := IntoReader(values)
if err != nil {
return err
}

headers := s.GetAuthHeaders(map[string]string{})
headers["scnt"] = s.Scnt
Expand All @@ -140,7 +148,7 @@ func (s *Session) Validate2FACode(ctx context.Context, code string) error {
NoResponse: true,
}

_, err := s.Request(ctx, opts, nil, nil)
_, err = s.Request(ctx, opts, nil, nil)
if err == nil {
if err := s.TrustSession(ctx); err != nil {
return err
Expand Down
31 changes: 21 additions & 10 deletions backend/icloud/icloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func init() {
Sensitive: true,
}, {
Name: configTrustToken,
Help: "trust token (internal use)",
Help: "Trust token (internal use)",
IsPassword: false,
Required: false,
Sensitive: true,
Expand All @@ -83,7 +83,7 @@ func init() {
Hide: fs.OptionHideBoth,
}, {
Name: configClientID,
Help: "client id",
Help: "Client id",
Required: false,
Advanced: true,
Default: "d39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d",
Expand Down Expand Up @@ -140,14 +140,18 @@ type Object struct {

// Config configures the iCloud remote.
func Config(ctx context.Context, name string, m configmap.Mapper, config fs.ConfigIn) (*fs.ConfigOut, error) {
appleid, _ := m.Get(configAppleID)
var err error
appleid, _ := m.Get(configAppleID)
if appleid == "" {
return nil, errors.New("a apple ID is required")
}

password, _ := m.Get(configPassword)
if password != "" {
password, _ = obscure.Reveal(password)
password, err = obscure.Reveal(password)
if err != nil {
return nil, err
}
}

trustToken, _ := m.Get(configTrustToken)
Expand All @@ -157,7 +161,10 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf

switch config.State {
case "":
icloud, _ := api.New(appleid, password, trustToken, clientID, cookies, nil)
icloud, err := api.New(appleid, password, trustToken, clientID, cookies, nil)
if err != nil {
return nil, err
}
if err := icloud.Authenticate(ctx); err != nil {
return nil, err
}
Expand All @@ -172,7 +179,10 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf
return fs.ConfigError("authenticate", "2FA codes can't be blank")
}

icloud, _ := api.New(appleid, password, trustToken, clientID, cookies, nil)
icloud, err := api.New(appleid, password, trustToken, clientID, cookies, nil)
if err != nil {
return nil, err
}
if err := icloud.SignIn(ctx); err != nil {
return nil, err
}
Expand All @@ -196,11 +206,9 @@ func Config(ctx context.Context, name string, m configmap.Mapper, config fs.Conf

// find item by path. Will not return any children for the item
func (f *Fs) findItem(ctx context.Context, dir string) (item *api.DriveItem, found bool, err error) {
service, _ := f.icloud.DriveService()

var resp *http.Response
if err = f.pacer.Call(func() (bool, error) {
item, resp, err = service.GetItemByPath(ctx, path.Join(f.root, dir))
item, resp, err = f.service.GetItemByPath(ctx, path.Join(f.root, dir))
return shouldRetry(ctx, resp, err)
}); err != nil {
if item == nil && resp.StatusCode == 404 {
Expand All @@ -212,7 +220,10 @@ func (f *Fs) findItem(ctx context.Context, dir string) (item *api.DriveItem, fou
}

func (f *Fs) findLeafItem(ctx context.Context, pathID string, leaf string) (item *api.DriveItem, found bool, err error) {
items, _ := f.listAll(ctx, pathID)
items, err := f.listAll(ctx, pathID)
if err != nil {
return nil, false, err
}
for _, item := range items {
if strings.EqualFold(item.FullName(), leaf) {
return item, true, nil
Expand Down

0 comments on commit 73f630b

Please sign in to comment.