imap-backup 2.1.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -4
- data/.rubocop_todo.yml +29 -11
- data/.travis.yml +1 -1
- data/README.md +10 -13
- data/bin/imap-backup +5 -2
- data/docs/01-credentials-screen.png +0 -0
- data/docs/02-new-project.png +0 -0
- data/docs/03-initial-credentials-for-project.png +0 -0
- data/docs/04-credential-type-selection.png +0 -0
- data/docs/05-cant-create-without-consent-setup.png +0 -0
- data/docs/06-user-type-selection.png +0 -0
- data/docs/07-consent-screen-form.png +0 -0
- data/docs/08-app-scopes.png +0 -0
- data/docs/09-scope-selection.png +0 -0
- data/docs/10-updated-app-scopes.png +0 -0
- data/docs/11-test-users.png +0 -0
- data/docs/12-add-users.png +0 -0
- data/docs/13-create-oauth-client.png +0 -0
- data/docs/14-application-details.png +0 -0
- data/docs/16-initial-menu.png +0 -0
- data/docs/17-inputting-the-email-address.png +0 -0
- data/docs/18-choose-password.png +0 -0
- data/docs/19-supply-client-info.png +0 -0
- data/docs/20-choose-gmail-account.png +0 -0
- data/docs/21-accept-warnings.png +0 -0
- data/docs/22-grant-access.png +0 -0
- data/docs/24-confirm-choices.png +0 -0
- data/docs/25-success-code.png +0 -0
- data/docs/26-type-code-into-imap-backup.png +0 -0
- data/docs/27-success.png +0 -0
- data/docs/setting-up-gmail.md +166 -0
- data/imap-backup.gemspec +3 -9
- data/lib/email/mboxrd/message.rb +4 -3
- data/lib/email/provider.rb +3 -1
- data/lib/gmail/authenticator.rb +160 -0
- data/lib/google/auth/stores/in_memory_token_store.rb +9 -0
- data/lib/imap/backup.rb +2 -1
- data/lib/imap/backup/account/connection.rb +59 -34
- data/lib/imap/backup/account/folder.rb +10 -1
- data/lib/imap/backup/configuration/account.rb +9 -1
- data/lib/imap/backup/configuration/gmail_oauth2.rb +82 -0
- data/lib/imap/backup/configuration/setup.rb +4 -1
- data/lib/imap/backup/serializer/mbox.rb +4 -0
- data/lib/imap/backup/serializer/mbox_enumerator.rb +1 -1
- data/lib/imap/backup/serializer/mbox_store.rb +20 -4
- data/lib/imap/backup/uploader.rb +10 -2
- data/lib/imap/backup/version.rb +5 -4
- data/spec/features/backup_spec.rb +3 -3
- data/spec/features/helper.rb +1 -1
- data/spec/features/restore_spec.rb +75 -27
- data/spec/features/support/backup_directory.rb +2 -2
- data/spec/features/support/email_server.rb +1 -3
- data/spec/features/support/shared/message_fixtures.rb +8 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/fixtures.rb +1 -1
- data/spec/unit/email/mboxrd/message_spec.rb +2 -8
- data/spec/unit/email/provider_spec.rb +2 -2
- data/spec/unit/gmail/authenticator_spec.rb +138 -0
- data/spec/unit/google/auth/stores/in_memory_token_store_spec.rb +15 -0
- data/spec/unit/imap/backup/account/connection_spec.rb +157 -79
- data/spec/unit/imap/backup/account/folder_spec.rb +30 -20
- data/spec/unit/imap/backup/configuration/account_spec.rb +65 -46
- data/spec/unit/imap/backup/configuration/asker_spec.rb +20 -17
- data/spec/unit/imap/backup/configuration/connection_tester_spec.rb +6 -10
- data/spec/unit/imap/backup/configuration/folder_chooser_spec.rb +16 -10
- data/spec/unit/imap/backup/configuration/gmail_oauth2_spec.rb +84 -0
- data/spec/unit/imap/backup/configuration/list_spec.rb +6 -3
- data/spec/unit/imap/backup/configuration/setup_spec.rb +89 -54
- data/spec/unit/imap/backup/configuration/store_spec.rb +18 -16
- data/spec/unit/imap/backup/downloader_spec.rb +14 -14
- data/spec/unit/imap/backup/serializer/mbox_enumerator_spec.rb +6 -1
- data/spec/unit/imap/backup/serializer/mbox_spec.rb +62 -40
- data/spec/unit/imap/backup/serializer/mbox_store_spec.rb +94 -35
- data/spec/unit/imap/backup/uploader_spec.rb +23 -7
- data/spec/unit/imap/backup/utils_spec.rb +10 -9
- metadata +68 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e4037b31fc56dcf88f312506ff2814b1c3fb516ae13cf9dbb4c8a772928b5fa
|
4
|
+
data.tar.gz: 0465b9bf0b7a6a9dadc5c6c35b1a4dd65db058ab1ed37158d9fedf2dc093f777
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 459620b79228707291d0b3be5037830e7100da42ecc920a1b5e19797fd1cc9aa9bc8fa667f5a5a7f89cc5d2647f47df5ae7e384a575c62a9bf4a13c25c70dd4b
|
7
|
+
data.tar.gz: 8ac9d67819df8f957ffbc6a93be59aa401bdec704d75fa637c186012d2f15e23c3efa5c68ca8dc8918c97de3d90623ee5627d3cb8107615ee108e76588afd054
|
data/.rubocop.yml
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
inherit_from:
|
2
|
-
- https://
|
2
|
+
- https://raw.githubusercontent.com/leanpanda-com/rubocop/0.89.1/rubocop-rspec.yml
|
3
3
|
- .rubocop_todo.yml
|
4
4
|
|
5
5
|
AllCops:
|
6
|
-
TargetRubyVersion: 2.3
|
7
6
|
Exclude:
|
8
7
|
- "bin/stubs/*"
|
9
8
|
DisplayCopNames:
|
@@ -12,8 +11,10 @@ AllCops:
|
|
12
11
|
RSpec/ContextWording:
|
13
12
|
Exclude:
|
14
13
|
- "spec/features/**/*"
|
15
|
-
RSpec/
|
16
|
-
|
14
|
+
RSpec/LeakyConstantDeclaration:
|
15
|
+
Enabled: false
|
16
|
+
RSpec/MessageSpies:
|
17
|
+
Enabled: false
|
17
18
|
RSpec/ReturnFromStub:
|
18
19
|
Enabled: false
|
19
20
|
Style/EmptyCaseCondition:
|
data/.rubocop_todo.yml
CHANGED
@@ -1,24 +1,42 @@
|
|
1
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2021-01-09 09:21:34 UTC using RuboCop version 0.89.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 11
|
10
|
+
# Configuration parameters: IgnoredMethods.
|
2
11
|
Metrics/AbcSize:
|
3
|
-
Max:
|
12
|
+
Max: 33
|
4
13
|
|
5
14
|
# Offense count: 2
|
6
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
15
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
|
7
16
|
# ExcludedMethods: refine
|
8
17
|
Metrics/BlockLength:
|
9
|
-
Max:
|
18
|
+
Max: 138
|
10
19
|
|
11
20
|
# Offense count: 2
|
12
|
-
# Configuration parameters: CountComments.
|
21
|
+
# Configuration parameters: CountComments, CountAsOne.
|
13
22
|
Metrics/ClassLength:
|
14
|
-
Max:
|
23
|
+
Max: 167
|
15
24
|
|
16
|
-
# Offense count:
|
17
|
-
# Configuration parameters: CountComments, ExcludedMethods.
|
25
|
+
# Offense count: 17
|
26
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
|
18
27
|
Metrics/MethodLength:
|
19
28
|
Max: 25
|
20
29
|
|
21
|
-
# Offense count:
|
22
|
-
# Configuration parameters: CountComments.
|
30
|
+
# Offense count: 2
|
31
|
+
# Configuration parameters: CountComments, CountAsOne.
|
23
32
|
Metrics/ModuleLength:
|
24
|
-
Max:
|
33
|
+
Max: 141
|
34
|
+
|
35
|
+
# Offense count: 200
|
36
|
+
# Configuration parameters: AllowSubject.
|
37
|
+
RSpec/MultipleMemoizedHelpers:
|
38
|
+
Max: 16
|
39
|
+
|
40
|
+
# Offense count: 1
|
41
|
+
RSpec/NestedGroups:
|
42
|
+
Max: 6
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -16,11 +16,11 @@
|
|
16
16
|
[Rubygem]: http://rubygems.org/gems/imap-backup "Ruby gem at rubygems.org"
|
17
17
|
[Continuous Integration]: http://travis-ci.org/joeyates/imap-backup "Build status by Travis-CI"
|
18
18
|
|
19
|
-
##
|
19
|
+
## GMail
|
20
|
+
|
21
|
+
GMail OAuth2 authentication is supported.
|
20
22
|
|
21
|
-
|
22
|
-
backwardly-incompatible way. When upgrading, all old backups will be gradually
|
23
|
-
deleted to allow for the new file format to be introduced.
|
23
|
+
To set it up, [follow the HOWTO](docs/setting-up-gmail.md).
|
24
24
|
|
25
25
|
# Installation
|
26
26
|
|
@@ -115,13 +115,6 @@ Specifically, if you are using a self-signed certificate and get SSL errors, e.g
|
|
115
115
|
}
|
116
116
|
```
|
117
117
|
|
118
|
-
## GMail
|
119
|
-
|
120
|
-
* Enable IMAP access to your account via the GMail interface (Settings/Forwarding and POP/IMAP),
|
121
|
-
* Under 'Sign-in & security', 'Signing in to Google', 'App passwords', generate a password
|
122
|
-
for imap-backup,
|
123
|
-
* In imap-backup setup, set the server to imap.gmail.com
|
124
|
-
|
125
118
|
# Security
|
126
119
|
|
127
120
|
Note that email usernames and passwords are held in plain text
|
@@ -204,8 +197,8 @@ Integration tests (feature specs) are run against a Docker image
|
|
204
197
|
|
205
198
|
In one shell, run the Docker image:
|
206
199
|
|
207
|
-
```
|
208
|
-
docker run \
|
200
|
+
```sh
|
201
|
+
$ docker run \
|
209
202
|
--env MAIL_ADDRESS=address@example.org \
|
210
203
|
--env MAIL_PASS=pass \
|
211
204
|
--env MAILNAME=example.org \
|
@@ -213,6 +206,10 @@ docker run \
|
|
213
206
|
antespi/docker-imap-devel:latest
|
214
207
|
```
|
215
208
|
|
209
|
+
```sh
|
210
|
+
$ rake
|
211
|
+
```
|
212
|
+
|
216
213
|
To exclude Docker-based tests:
|
217
214
|
|
218
215
|
```sh
|
data/bin/imap-backup
CHANGED
@@ -48,12 +48,15 @@ parser.parse!
|
|
48
48
|
|
49
49
|
options[:command] = ARGV.shift if !ARGV.empty?
|
50
50
|
|
51
|
+
# rubocop:disable Style/IfUnlessModifier
|
51
52
|
if KNOWN_COMMANDS.find { |c| c[:name] == options[:command] }.nil?
|
52
53
|
raise "Unknown command '#{options[:command]}'"
|
53
54
|
end
|
54
55
|
|
56
|
+
# rubocop:enable Style/IfUnlessModifier
|
57
|
+
|
55
58
|
if options[:command] == "help"
|
56
|
-
puts
|
59
|
+
puts parser
|
57
60
|
exit
|
58
61
|
end
|
59
62
|
|
@@ -79,7 +82,7 @@ when "folders"
|
|
79
82
|
warn "Unable to list account folders"
|
80
83
|
exit 1
|
81
84
|
end
|
82
|
-
folders.each { |f| puts "\t
|
85
|
+
folders.each { |f| puts "\t#{f.name}" }
|
83
86
|
end
|
84
87
|
when "restore"
|
85
88
|
configuration.each_connection(&:restore)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/docs/27-success.png
ADDED
Binary file
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# Setting up GMail Authentication for imap-backup
|
2
|
+
|
3
|
+
# Create a Google project
|
4
|
+
|
5
|
+
Go to https://console.developers.google.com
|
6
|
+
|
7
|
+
Select "Credentials".
|
8
|
+
|
9
|
+
![Credential screen](01-credentials-screen.png)
|
10
|
+
|
11
|
+
Select "CREATE PROJECT".
|
12
|
+
|
13
|
+
![New project](02-new-project.png)
|
14
|
+
|
15
|
+
Set or accept the "Project name",
|
16
|
+
|
17
|
+
And optionally do the same with the "Project ID",
|
18
|
+
|
19
|
+
Leave "Location" on "No organization",
|
20
|
+
|
21
|
+
Click "CREATE".
|
22
|
+
|
23
|
+
![Initial project credentials](03-initial-credentials-for-project.png)
|
24
|
+
|
25
|
+
Click "+ CREATE CREDENTIALS".
|
26
|
+
|
27
|
+
![Credential type selection](04-credential-type-selection.png)
|
28
|
+
|
29
|
+
Select "OAuth client ID".
|
30
|
+
|
31
|
+
![Can't create credentials before setting up the consent screen](05-cant-create-without-consent-setup.png)
|
32
|
+
|
33
|
+
Click "CONFIGURE CONSENT SCREEN".
|
34
|
+
|
35
|
+
![User type selection](06-user-type-selection.png)
|
36
|
+
|
37
|
+
Select "External",
|
38
|
+
|
39
|
+
Click "CREATE".
|
40
|
+
|
41
|
+
![Consent screen form](07-consent-screen-form.png)
|
42
|
+
|
43
|
+
Fill in "App name",
|
44
|
+
|
45
|
+
Select your email as "User support email",
|
46
|
+
|
47
|
+
Type in your email at the bottom under "Developer contact information",
|
48
|
+
|
49
|
+
Click "SAVE AND CONTINUE".
|
50
|
+
|
51
|
+
![App scopes](08-app-scopes.png)
|
52
|
+
|
53
|
+
Click "ADD OR REMOVE SCOPES".
|
54
|
+
|
55
|
+
![Scope selection](09-scope-selection.png)
|
56
|
+
|
57
|
+
Under "Manually add scopes", type "https://mail.google.com/",
|
58
|
+
|
59
|
+
Click "ADD TO TABLE",
|
60
|
+
|
61
|
+
Click "UPDATE".
|
62
|
+
|
63
|
+
![Updated app scopes](10-updated-app-scopes.png)
|
64
|
+
|
65
|
+
Click "SAVE AND CONTINUE".
|
66
|
+
|
67
|
+
![Test users](11-test-users.png)
|
68
|
+
|
69
|
+
Click "+ ADD USERS".
|
70
|
+
|
71
|
+
![Add users](12-add-users.png)
|
72
|
+
|
73
|
+
Type in your email,
|
74
|
+
|
75
|
+
Click "SAVE AND CONTINUE",
|
76
|
+
|
77
|
+
Click "BACK TO DASHBOARD",
|
78
|
+
|
79
|
+
Click "Credentials" in the menu
|
80
|
+
|
81
|
+
And then click "+ CREATE CREDENTIALS" again,
|
82
|
+
|
83
|
+
And select "OAuth client ID" again.
|
84
|
+
|
85
|
+
![Create OAuth client](13-create-oauth-client.png)
|
86
|
+
|
87
|
+
This time you will be able to proceed.
|
88
|
+
|
89
|
+
![Application details](14-application-details.png)
|
90
|
+
|
91
|
+
Select "TVs and limited input devices",
|
92
|
+
|
93
|
+
Click "CREATE",
|
94
|
+
|
95
|
+
Copy both "Your Client ID"
|
96
|
+
|
97
|
+
And "Your Client Secret".
|
98
|
+
|
99
|
+
# Set up imap-backup
|
100
|
+
|
101
|
+
Run `imap-backup setup`.
|
102
|
+
|
103
|
+
![Initial imap-backup menu](16-initial-menu.png)
|
104
|
+
|
105
|
+
Choose 'add account'.
|
106
|
+
|
107
|
+
![Type in your email address](17-inputting-the-email-address.png)
|
108
|
+
|
109
|
+
Type in your GMail address.
|
110
|
+
|
111
|
+
Note: if you have a custom domain (GSuite) address,
|
112
|
+
e.g. "me@mycompany.com", you now need to
|
113
|
+
choose 'server' and
|
114
|
+
type in 'imap.gmail.com'.
|
115
|
+
|
116
|
+
![Choose password](18-choose-password.png)
|
117
|
+
|
118
|
+
Choose `password`.
|
119
|
+
|
120
|
+
![Supply client info](19-supply-client-info.png)
|
121
|
+
|
122
|
+
Type your "Client ID" and "Client Secret",
|
123
|
+
|
124
|
+
Next you will be shown a URL to open in your browser.
|
125
|
+
|
126
|
+
![Choose GMail account](20-choose-gmail-account.png)
|
127
|
+
|
128
|
+
If you have more than one GMail account you will need to choose which
|
129
|
+
you are configuring.
|
130
|
+
|
131
|
+
![Accept warnings](21-accept-warnings.png)
|
132
|
+
|
133
|
+
As the project "app" is in test mode,
|
134
|
+
you'll need to accept to ignore this warning.
|
135
|
+
|
136
|
+
Click "Advanced",
|
137
|
+
|
138
|
+
Then click "Go to XXXYYYZZZ (unsafe)"
|
139
|
+
|
140
|
+
![Grant access](22-grant-access.png)
|
141
|
+
|
142
|
+
Choose "Allow".
|
143
|
+
|
144
|
+
![Confirm choices](24-confirm-choices.png)
|
145
|
+
|
146
|
+
Choose "Allow".
|
147
|
+
|
148
|
+
![Success code screen](25-success-code.png)
|
149
|
+
|
150
|
+
Click on the copy logo to copy the success code.
|
151
|
+
|
152
|
+
![Paste the code](26-type-code-into-imap_backup.png)
|
153
|
+
|
154
|
+
Paste the success code into imap-backup.
|
155
|
+
|
156
|
+
Finally, choose 'test connection'.
|
157
|
+
|
158
|
+
If all has gone well you should see this:
|
159
|
+
|
160
|
+
![Connection successful](27-success.png)
|
161
|
+
|
162
|
+
Now choose 'return to main menu',
|
163
|
+
|
164
|
+
Then 'save and exit'.
|
165
|
+
|
166
|
+
Your imap-backup is now configured to back up your GMail.
|
data/imap-backup.gemspec
CHANGED
@@ -13,17 +13,11 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
14
14
|
gem.test_files = gem.files.grep(%r{^spec/})
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.required_ruby_version = [">= 2.
|
16
|
+
gem.required_ruby_version = [">= 2.4.0"]
|
17
17
|
gem.version = Imap::Backup::VERSION
|
18
18
|
|
19
|
-
gem.
|
20
|
-
|
21
|
-
the metadata storage method has changed (from flat file to JSON).
|
22
|
-
|
23
|
-
As a result, on the first run after an upgrade, old backup folders will be
|
24
|
-
**deleted** and a full new backup created.
|
25
|
-
MESSAGE
|
26
|
-
|
19
|
+
gem.add_runtime_dependency "gmail_xoauth"
|
20
|
+
gem.add_runtime_dependency "googleauth"
|
27
21
|
gem.add_runtime_dependency "highline"
|
28
22
|
gem.add_runtime_dependency "mail"
|
29
23
|
gem.add_runtime_dependency "rake"
|
data/lib/email/mboxrd/message.rb
CHANGED
@@ -10,19 +10,20 @@ module Email::Mboxrd
|
|
10
10
|
cleaned = serialized.gsub(/^>(>*From)/, "\\1")
|
11
11
|
# Serialized messages in this format *should* start with a line
|
12
12
|
# From xxx yy zz
|
13
|
+
# rubocop:disable Style/IfUnlessModifier
|
13
14
|
if cleaned.start_with?("From ")
|
14
15
|
cleaned = cleaned.sub(/^From .*[\r\n]*/, "")
|
15
16
|
end
|
17
|
+
# rubocop:enable Style/IfUnlessModifier
|
16
18
|
new(cleaned)
|
17
19
|
end
|
18
20
|
|
19
21
|
def initialize(supplied_body)
|
20
22
|
@supplied_body = supplied_body.clone
|
21
|
-
@supplied_body.force_encoding("binary")
|
22
23
|
end
|
23
24
|
|
24
25
|
def to_serialized
|
25
|
-
"From
|
26
|
+
"From #{from}\n" + mboxrd_body
|
26
27
|
end
|
27
28
|
|
28
29
|
def date
|
@@ -45,7 +46,7 @@ module Email::Mboxrd
|
|
45
46
|
@from ||=
|
46
47
|
begin
|
47
48
|
from = best_from.dup
|
48
|
-
from << " "
|
49
|
+
from << " #{asctime}" if asctime != ""
|
49
50
|
from
|
50
51
|
end
|
51
52
|
end
|