imap-backup 3.2.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +51 -0
- data/.rubocop_todo.yml +103 -16
- data/README.md +19 -5
- data/Rakefile +6 -0
- data/bin/imap-backup +1 -1
- data/docs/{setting-up-gmail.md → setting-up-gmail-with-oauth2.md} +0 -0
- data/imap-backup.gemspec +1 -0
- data/lib/imap/backup/account/connection.rb +11 -4
- data/lib/imap/backup/configuration/account.rb +6 -1
- data/lib/imap/backup/configuration/gmail_oauth2.rb +26 -6
- data/lib/imap/backup/version.rb +1 -1
- data/spec/fixtures/connection.yml +1 -1
- data/spec/support/fixtures.rb +7 -2
- data/spec/unit/gmail/authenticator_spec.rb +1 -1
- data/spec/unit/imap/backup/account/connection_spec.rb +27 -1
- data/spec/unit/imap/backup/configuration/account_spec.rb +37 -8
- data/spec/unit/imap/backup/configuration/gmail_oauth2_spec.rb +42 -5
- data/spec/unit/imap/backup/configuration/setup_spec.rb +1 -1
- data/spec/unit/imap/backup/utils_spec.rb +0 -2
- metadata +19 -5
- data/.travis.yml +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44a7f8e8754461ed51afdbd5711ba809ad6b0ed68c0f40ff95a42688d85881b9
|
4
|
+
data.tar.gz: a70019109a179506f520b969bb03de78fa67fca66001b182af99427b7a02ecdd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5055eea6a69b674f02f2b50c0423df197a4c312171aa04a19b183ce784047699815ac603d8550d28f78ada6f2aa4a904d74d5b7bef8f6ea10633de68752f7a65
|
7
|
+
data.tar.gz: 7849285c5b94136b7d5f620eac770630ea4e7cf988b42cc7079021dac95163c271f5fd68d5b620ac9d36326be142557c617459ba890755920c181110cf99531a
|
@@ -0,0 +1,51 @@
|
|
1
|
+
version: 2.1
|
2
|
+
|
3
|
+
orbs:
|
4
|
+
ruby: circleci/ruby@1.1.2
|
5
|
+
|
6
|
+
references:
|
7
|
+
restore: &restore
|
8
|
+
restore_cache:
|
9
|
+
keys:
|
10
|
+
- 'imap.backup.<< parameters.ruby_version >>.{{checksum "imap-backup.gemspec"}}'
|
11
|
+
bundle: &bundle
|
12
|
+
run:
|
13
|
+
name: Install Ruby dependencies
|
14
|
+
command: |
|
15
|
+
bundle install
|
16
|
+
bundle clean
|
17
|
+
save: &save
|
18
|
+
save_cache:
|
19
|
+
key: 'imap.backup.<< parameters.ruby_version >>.{{checksum "imap-backup.gemspec"}}'
|
20
|
+
paths:
|
21
|
+
- vendor/bundle
|
22
|
+
|
23
|
+
jobs:
|
24
|
+
test:
|
25
|
+
parameters:
|
26
|
+
ruby_version:
|
27
|
+
type: string
|
28
|
+
environment:
|
29
|
+
BUNDLE_PATH: ./vendor/bundle
|
30
|
+
DOCKER_IMAP_PORT: 993
|
31
|
+
docker:
|
32
|
+
- image: "cimg/ruby:<< parameters.ruby_version >>"
|
33
|
+
- image: antespi/docker-imap-devel:latest
|
34
|
+
environment:
|
35
|
+
MAIL_ADDRESS: address@example.org
|
36
|
+
MAIL_PASS: pass
|
37
|
+
MAILNAME: example.org
|
38
|
+
steps:
|
39
|
+
- checkout
|
40
|
+
- <<: *restore
|
41
|
+
- <<: *bundle
|
42
|
+
- <<: *save
|
43
|
+
- ruby/rspec-test
|
44
|
+
|
45
|
+
workflows:
|
46
|
+
all-tests:
|
47
|
+
jobs:
|
48
|
+
- test:
|
49
|
+
matrix:
|
50
|
+
parameters:
|
51
|
+
ruby_version: ["2.4", "2.5", "2.6", "2.7"]
|
data/.rubocop_todo.yml
CHANGED
@@ -1,42 +1,129 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2021-
|
3
|
+
# on 2021-09-21 15:30:34 UTC using RuboCop version 1.21.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
10
|
-
#
|
11
|
-
|
12
|
-
|
9
|
+
# Offense count: 1
|
10
|
+
# Cop supports --auto-correct.
|
11
|
+
Layout/ElseAlignment:
|
12
|
+
Exclude:
|
13
|
+
- 'lib/imap/backup/configuration/gmail_oauth2.rb'
|
13
14
|
|
14
15
|
# Offense count: 2
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
18
|
-
|
16
|
+
# Cop supports --auto-correct.
|
17
|
+
# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines.
|
18
|
+
Layout/EmptyLineBetweenDefs:
|
19
|
+
Exclude:
|
20
|
+
- 'lib/google/auth/stores/in_memory_token_store.rb'
|
21
|
+
|
22
|
+
# Offense count: 1
|
23
|
+
# Cop supports --auto-correct.
|
24
|
+
# Configuration parameters: EnforcedStyleAlignWith, Severity.
|
25
|
+
# SupportedStylesAlignWith: keyword, variable, start_of_line
|
26
|
+
Layout/EndAlignment:
|
27
|
+
Exclude:
|
28
|
+
- 'lib/imap/backup/configuration/gmail_oauth2.rb'
|
29
|
+
|
30
|
+
# Offense count: 1
|
31
|
+
# Cop supports --auto-correct.
|
32
|
+
# Configuration parameters: Width, IgnoredPatterns.
|
33
|
+
Layout/IndentationWidth:
|
34
|
+
Exclude:
|
35
|
+
- 'lib/imap/backup/configuration/gmail_oauth2.rb'
|
36
|
+
|
37
|
+
# Offense count: 34
|
38
|
+
# Configuration parameters: AllowedMethods.
|
39
|
+
# AllowedMethods: enums
|
40
|
+
Lint/ConstantDefinitionInBlock:
|
41
|
+
Exclude:
|
42
|
+
- 'lib/imap/backup/configuration/asker.rb'
|
43
|
+
- 'spec/unit/gmail/authenticator_spec.rb'
|
44
|
+
- 'spec/unit/google/auth/stores/in_memory_token_store_spec.rb'
|
45
|
+
- 'spec/unit/imap/backup/account/connection_spec.rb'
|
46
|
+
- 'spec/unit/imap/backup/account/folder_spec.rb'
|
47
|
+
- 'spec/unit/imap/backup/configuration/account_spec.rb'
|
48
|
+
- 'spec/unit/imap/backup/configuration/gmail_oauth2_spec.rb'
|
19
49
|
|
20
50
|
# Offense count: 2
|
51
|
+
# Cop supports --auto-correct.
|
52
|
+
# Configuration parameters: AllowComments.
|
53
|
+
Lint/UselessMethodDefinition:
|
54
|
+
Exclude:
|
55
|
+
- 'lib/imap/backup/configuration/account.rb'
|
56
|
+
- 'lib/imap/backup/configuration/asker.rb'
|
57
|
+
|
58
|
+
# Offense count: 11
|
59
|
+
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
|
60
|
+
Metrics/AbcSize:
|
61
|
+
Max: 33
|
62
|
+
|
63
|
+
# Offense count: 3
|
21
64
|
# Configuration parameters: CountComments, CountAsOne.
|
22
65
|
Metrics/ClassLength:
|
23
|
-
Max:
|
66
|
+
Max: 171
|
24
67
|
|
25
|
-
# Offense count:
|
26
|
-
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
|
68
|
+
# Offense count: 19
|
69
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
27
70
|
Metrics/MethodLength:
|
28
|
-
Max:
|
71
|
+
Max: 26
|
29
72
|
|
30
73
|
# Offense count: 2
|
31
74
|
# Configuration parameters: CountComments, CountAsOne.
|
32
75
|
Metrics/ModuleLength:
|
33
|
-
Max:
|
76
|
+
Max: 145
|
77
|
+
|
78
|
+
# Offense count: 2
|
79
|
+
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
|
80
|
+
# SupportedStyles: snake_case, normalcase, non_integer
|
81
|
+
# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
|
82
|
+
Naming/VariableNumber:
|
83
|
+
Exclude:
|
84
|
+
- 'lib/email/provider.rb'
|
85
|
+
- 'spec/unit/email/provider_spec.rb'
|
34
86
|
|
35
|
-
# Offense count:
|
87
|
+
# Offense count: 209
|
36
88
|
# Configuration parameters: AllowSubject.
|
37
89
|
RSpec/MultipleMemoizedHelpers:
|
38
90
|
Max: 16
|
39
91
|
|
40
|
-
# Offense count:
|
92
|
+
# Offense count: 49
|
41
93
|
RSpec/NestedGroups:
|
42
94
|
Max: 6
|
95
|
+
|
96
|
+
# Offense count: 8
|
97
|
+
# Cop supports --auto-correct.
|
98
|
+
# Configuration parameters: EnforcedStyle.
|
99
|
+
# SupportedStyles: nested, compact
|
100
|
+
Style/ClassAndModuleChildren:
|
101
|
+
Exclude:
|
102
|
+
- 'lib/email/mboxrd/message.rb'
|
103
|
+
- 'lib/imap/backup/downloader.rb'
|
104
|
+
- 'lib/imap/backup/serializer.rb'
|
105
|
+
- 'lib/imap/backup/serializer/mbox.rb'
|
106
|
+
- 'lib/imap/backup/serializer/mbox_enumerator.rb'
|
107
|
+
- 'lib/imap/backup/serializer/mbox_store.rb'
|
108
|
+
- 'lib/imap/backup/uploader.rb'
|
109
|
+
- 'lib/imap/backup/utils.rb'
|
110
|
+
|
111
|
+
# Offense count: 1
|
112
|
+
# Cop supports --auto-correct.
|
113
|
+
Style/RedundantBegin:
|
114
|
+
Exclude:
|
115
|
+
- 'lib/imap/backup/account/connection.rb'
|
116
|
+
|
117
|
+
# Offense count: 1
|
118
|
+
# Cop supports --auto-correct.
|
119
|
+
# Configuration parameters: MinSize, WordRegex.
|
120
|
+
# SupportedStyles: percent, brackets
|
121
|
+
Style/WordArray:
|
122
|
+
EnforcedStyle: percent
|
123
|
+
|
124
|
+
# Offense count: 1
|
125
|
+
# Cop supports --auto-correct.
|
126
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
127
|
+
# URISchemes: http, https
|
128
|
+
Layout/LineLength:
|
129
|
+
Max: 133
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[![Build Status](https://
|
1
|
+
[![Build Status](https://circleci.com/gh/joeyates/imap-backup.svg?style=svg)][Continuous Integration]
|
2
2
|
[![Source Analysis](https://codeclimate.com/github/joeyates/imap-backup/badges/gpa.svg)](https://codeclimate.com/github/joeyates/imap-backup)
|
3
3
|
[![Test Coverage](https://codeclimate.com/github/joeyates/imap-backup/badges/coverage.svg)](https://codeclimate.com/github/joeyates/imap-backup/coverage)
|
4
4
|
|
@@ -14,13 +14,21 @@
|
|
14
14
|
[Source Code]: https://github.com/joeyates/imap-backup "Source code at GitHub"
|
15
15
|
[API documentation]: http://rubydoc.info/gems/imap-backup/frames "RDoc API Documentation at Rubydoc.info"
|
16
16
|
[Rubygem]: http://rubygems.org/gems/imap-backup "Ruby gem at rubygems.org"
|
17
|
-
[Continuous Integration]:
|
17
|
+
[Continuous Integration]: https://circleci.com/gh/joeyates/imap-backup "Build status by CirceCI"
|
18
18
|
|
19
|
-
|
19
|
+
# GMail
|
20
20
|
|
21
|
-
GMail
|
21
|
+
To use imap-backup with GMail, you will need to enable 'App passwords' on your account.
|
22
22
|
|
23
|
-
|
23
|
+
## GMail OAuth2
|
24
|
+
|
25
|
+
GMail OAuth2 authentication is supported, but as GMail's policy requires
|
26
|
+
users to set up an application specific to their account, the feature
|
27
|
+
is disabled by default.
|
28
|
+
|
29
|
+
You will need to set the environment variable IMAP_BACKUP_ENABLE_GMAIL_OAUTH2.
|
30
|
+
|
31
|
+
To set it up, [follow the HOWTO](docs/setting-up-gmail-with-oauth2.md).
|
24
32
|
|
25
33
|
# Installation
|
26
34
|
|
@@ -212,6 +220,12 @@ $ rake
|
|
212
220
|
|
213
221
|
To exclude Docker-based tests:
|
214
222
|
|
223
|
+
```sh
|
224
|
+
rake no-docker
|
225
|
+
```
|
226
|
+
|
227
|
+
or
|
228
|
+
|
215
229
|
```sh
|
216
230
|
$ rspec --tag ~docker
|
217
231
|
```
|
data/Rakefile
CHANGED
@@ -6,6 +6,12 @@ RSpec::Core::RakeTask.new do |t|
|
|
6
6
|
t.pattern = "spec/**/*_spec.rb"
|
7
7
|
end
|
8
8
|
|
9
|
+
desc "Run RSpec examples, excluding ones relying on Docker IMAP"
|
10
|
+
RSpec::Core::RakeTask.new("no-docker") do |t|
|
11
|
+
t.pattern = "spec/**/*_spec.rb"
|
12
|
+
t.rspec_opts = "--tag ~docker"
|
13
|
+
end
|
14
|
+
|
9
15
|
RuboCop::RakeTask.new
|
10
16
|
|
11
17
|
task default: :spec
|
data/bin/imap-backup
CHANGED
File without changes
|
data/imap-backup.gemspec
CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |gem|
|
|
29
29
|
gem.add_development_dependency "pry-byebug"
|
30
30
|
end
|
31
31
|
gem.add_development_dependency "rspec", ">= 3.0.0"
|
32
|
+
gem.add_development_dependency "rspec_junit_formatter"
|
32
33
|
gem.add_development_dependency "rubocop-rspec"
|
33
34
|
gem.add_development_dependency "simplecov"
|
34
35
|
end
|
@@ -64,7 +64,12 @@ module Imap::Backup
|
|
64
64
|
|
65
65
|
Imap::Backup.logger.debug "[#{folder.name}] running backup"
|
66
66
|
serializer.apply_uid_validity(folder.uid_validity)
|
67
|
-
|
67
|
+
begin
|
68
|
+
Downloader.new(folder, serializer).run
|
69
|
+
rescue Net::IMAP::ByeResponseError
|
70
|
+
reconnect
|
71
|
+
retry
|
72
|
+
end
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
@@ -91,7 +96,7 @@ module Imap::Backup
|
|
91
96
|
"Creating IMAP instance: #{server}, options: #{options.inspect}"
|
92
97
|
)
|
93
98
|
imap = Net::IMAP.new(server, options)
|
94
|
-
if
|
99
|
+
if use_gmail_oauth2? && Gmail::Authenticator.refresh_token?(password)
|
95
100
|
authenticator = Gmail::Authenticator.new(email: username, token: password)
|
96
101
|
credentials = authenticator.credentials
|
97
102
|
raise InvalidGmailOauth2RefreshToken if !credentials
|
@@ -163,8 +168,10 @@ module Imap::Backup
|
|
163
168
|
password.gsub(/./, "x")
|
164
169
|
end
|
165
170
|
|
166
|
-
def
|
167
|
-
|
171
|
+
def use_gmail_oauth2?
|
172
|
+
# TODO: test use of ENV
|
173
|
+
server == Email::Provider::GMAIL_IMAP_SERVER &&
|
174
|
+
ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"]
|
168
175
|
end
|
169
176
|
|
170
177
|
def local_folders
|
@@ -69,7 +69,7 @@ module Imap::Backup
|
|
69
69
|
def modify_password(menu)
|
70
70
|
menu.choice("modify password") do
|
71
71
|
password =
|
72
|
-
if account
|
72
|
+
if use_gmail_oauth2?(account)
|
73
73
|
Configuration::GmailOauth2.new(account).run
|
74
74
|
else
|
75
75
|
Configuration::Asker.password
|
@@ -82,6 +82,11 @@ module Imap::Backup
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
def use_gmail_oauth2?(account)
|
86
|
+
account[:server] == Email::Provider::GMAIL_IMAP_SERVER &&
|
87
|
+
ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"]
|
88
|
+
end
|
89
|
+
|
85
90
|
def modify_server(menu)
|
86
91
|
menu.choice("modify server") do
|
87
92
|
server = highline.ask("server: ")
|
@@ -8,7 +8,7 @@ module Imap::Backup
|
|
8
8
|
You need to authorize imap_backup to get access to your email.
|
9
9
|
To do so, please follow the instructions here:
|
10
10
|
|
11
|
-
https://github.com/joeyates/imap-backup/docs/setting-up-gmail.md
|
11
|
+
https://github.com/joeyates/imap-backup/blob/main/docs/setting-up-gmail-with-oauth2.md
|
12
12
|
|
13
13
|
BANNER
|
14
14
|
|
@@ -26,8 +26,20 @@ module Imap::Backup
|
|
26
26
|
def run
|
27
27
|
Kernel.system("clear")
|
28
28
|
Kernel.puts BANNER
|
29
|
-
|
30
|
-
|
29
|
+
|
30
|
+
keep = if token.valid?
|
31
|
+
highline.agree("Use existing client info?")
|
32
|
+
else
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
if keep
|
37
|
+
@client_id = token.client_id
|
38
|
+
@client_secret = token.client_secret
|
39
|
+
else
|
40
|
+
@client_id = highline.ask("client_id: ")
|
41
|
+
@client_secret = highline.ask("client_secret: ")
|
42
|
+
end
|
31
43
|
|
32
44
|
Kernel.puts <<~MESSAGE
|
33
45
|
|
@@ -46,9 +58,9 @@ module Imap::Backup
|
|
46
58
|
|
47
59
|
raise "Failed" if !@credentials
|
48
60
|
|
49
|
-
|
50
|
-
|
51
|
-
|
61
|
+
new_token = JSON.parse(token_store.load(email))
|
62
|
+
new_token["client_secret"] = client_secret
|
63
|
+
new_token.to_json
|
52
64
|
end
|
53
65
|
|
54
66
|
private
|
@@ -57,6 +69,14 @@ module Imap::Backup
|
|
57
69
|
account[:username]
|
58
70
|
end
|
59
71
|
|
72
|
+
def password
|
73
|
+
account[:password]
|
74
|
+
end
|
75
|
+
|
76
|
+
def token
|
77
|
+
@token ||= Gmail::Authenticator::ImapBackupToken.new(password)
|
78
|
+
end
|
79
|
+
|
60
80
|
def highline
|
61
81
|
Configuration::Setup.highline
|
62
82
|
end
|
data/lib/imap/backup/version.rb
CHANGED
data/spec/support/fixtures.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "yaml"
|
3
|
+
|
1
4
|
def fixture(name)
|
2
5
|
spec_root = File.expand_path("..", File.dirname(__FILE__))
|
3
6
|
fixture_path = File.join(spec_root, "fixtures", "#{name}.yml")
|
4
|
-
|
5
|
-
|
7
|
+
content = File.read(fixture_path)
|
8
|
+
template = ERB.new(content)
|
9
|
+
yaml = template.result(binding)
|
10
|
+
YAML.safe_load(yaml, [Symbol])
|
6
11
|
end
|
@@ -111,7 +111,15 @@ describe Imap::Backup::Account::Connection do
|
|
111
111
|
with(email: USERNAME, token: PASSWORD) { authenticator }
|
112
112
|
end
|
113
113
|
|
114
|
-
context "when the password is our copy of a GMail refresh token" do
|
114
|
+
context "when the password is our copy of a GMail refresh token and the environment IMAP_BACKUP_ENABLE_GMAIL_OAUTH2 is set" do
|
115
|
+
before do
|
116
|
+
ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"] = "1"
|
117
|
+
end
|
118
|
+
|
119
|
+
after do
|
120
|
+
ENV.delete("IMAP_BACKUP_ENABLE_GMAIL_OAUTH2")
|
121
|
+
end
|
122
|
+
|
115
123
|
it "uses the OAuth2 access_token to authenticate" do
|
116
124
|
subject.imap
|
117
125
|
|
@@ -288,6 +296,24 @@ describe Imap::Backup::Account::Connection do
|
|
288
296
|
end
|
289
297
|
end
|
290
298
|
|
299
|
+
context "when the IMAP session expires" do
|
300
|
+
before do
|
301
|
+
data = OpenStruct.new(data: "Session expired")
|
302
|
+
response = OpenStruct.new(data: data)
|
303
|
+
outcomes = [
|
304
|
+
-> { raise Net::IMAP::ByeResponseError, response },
|
305
|
+
-> { nil }
|
306
|
+
]
|
307
|
+
allow(downloader).to receive(:run) { outcomes.shift.call }
|
308
|
+
end
|
309
|
+
|
310
|
+
it "reconnects" do
|
311
|
+
expect(downloader).to receive(:run).exactly(:twice)
|
312
|
+
|
313
|
+
subject.run_backup
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
291
317
|
context "when run" do
|
292
318
|
before { subject.run_backup }
|
293
319
|
|
@@ -214,16 +214,10 @@ describe Imap::Backup::Configuration::Account do
|
|
214
214
|
|
215
215
|
describe "choosing 'modify password'" do
|
216
216
|
let(:new_password) { "new_password" }
|
217
|
-
let(:gmail_oauth2) do
|
218
|
-
instance_double(Imap::Backup::Configuration::GmailOauth2, run: nil)
|
219
|
-
end
|
220
217
|
|
221
218
|
before do
|
222
219
|
allow(Imap::Backup::Configuration::Asker).
|
223
220
|
to receive(:password) { new_password }
|
224
|
-
allow(Imap::Backup::Configuration::GmailOauth2).
|
225
|
-
to receive(:new).
|
226
|
-
with(account) { gmail_oauth2 }
|
227
221
|
subject.run
|
228
222
|
menu.choices["modify password"].call
|
229
223
|
end
|
@@ -245,14 +239,49 @@ describe Imap::Backup::Configuration::Account do
|
|
245
239
|
|
246
240
|
include_examples "it doesn't flag the account as modified"
|
247
241
|
end
|
242
|
+
end
|
248
243
|
|
249
|
-
|
250
|
-
|
244
|
+
describe "choosing 'modify password' when the server is for GMail" do
|
245
|
+
let(:new_password) { "new_password" }
|
246
|
+
let(:current_server) { GMAIL_IMAP_SERVER }
|
247
|
+
let(:gmail_oauth2) do
|
248
|
+
instance_double(Imap::Backup::Configuration::GmailOauth2, run: nil)
|
249
|
+
end
|
250
|
+
|
251
|
+
before do
|
252
|
+
allow(Imap::Backup::Configuration::Asker).
|
253
|
+
to receive(:password) { new_password }
|
254
|
+
allow(Imap::Backup::Configuration::GmailOauth2).
|
255
|
+
to receive(:new).
|
256
|
+
with(account) { gmail_oauth2 }
|
257
|
+
end
|
258
|
+
|
259
|
+
context "when the environment IMAP_BACKUP_ENABLE_GMAIL_OAUTH2 is set" do
|
260
|
+
before do
|
261
|
+
ENV["IMAP_BACKUP_ENABLE_GMAIL_OAUTH2"] = "1"
|
262
|
+
subject.run
|
263
|
+
menu.choices["modify password"].call
|
264
|
+
end
|
265
|
+
|
266
|
+
after do
|
267
|
+
ENV.delete("IMAP_BACKUP_ENABLE_GMAIL_OAUTH2")
|
268
|
+
end
|
251
269
|
|
252
270
|
it "sets up GMail OAuth2" do
|
253
271
|
expect(gmail_oauth2).to have_received(:run)
|
254
272
|
end
|
255
273
|
end
|
274
|
+
|
275
|
+
context "when the environment IMAP_BACKUP_ENABLE_GMAIL_OAUTH2 is not set" do
|
276
|
+
before do
|
277
|
+
subject.run
|
278
|
+
menu.choices["modify password"].call
|
279
|
+
end
|
280
|
+
|
281
|
+
it "sets up GMail OAuth2" do
|
282
|
+
expect(gmail_oauth2).to_not have_received(:run)
|
283
|
+
end
|
284
|
+
end
|
256
285
|
end
|
257
286
|
|
258
287
|
describe "choosing 'modify server'" do
|
@@ -1,6 +1,9 @@
|
|
1
1
|
describe Imap::Backup::Configuration::GmailOauth2 do
|
2
2
|
include HighLineTestHelpers
|
3
3
|
|
4
|
+
CLIENT_ID = "my_client_id".freeze
|
5
|
+
CLIENT_SECRET = "my_client_secret".freeze
|
6
|
+
|
4
7
|
subject { described_class.new(account) }
|
5
8
|
|
6
9
|
let(:authorization_url) { "some long authorization_url" }
|
@@ -11,6 +14,7 @@ describe Imap::Backup::Configuration::GmailOauth2 do
|
|
11
14
|
let(:input) { highline_streams[0] }
|
12
15
|
let(:output) { highline_streams[1] }
|
13
16
|
let(:account) { {} }
|
17
|
+
let(:user_input) { %W(my_client_id\n my_secret\n my_code\n) }
|
14
18
|
|
15
19
|
let(:authorizer) do
|
16
20
|
instance_double(
|
@@ -25,23 +29,31 @@ describe Imap::Backup::Configuration::GmailOauth2 do
|
|
25
29
|
load: json_token
|
26
30
|
)
|
27
31
|
end
|
32
|
+
let(:token) do
|
33
|
+
instance_double(
|
34
|
+
Gmail::Authenticator::ImapBackupToken,
|
35
|
+
valid?: valid,
|
36
|
+
client_id: CLIENT_ID,
|
37
|
+
client_secret: CLIENT_SECRET
|
38
|
+
)
|
39
|
+
end
|
40
|
+
let(:valid) { false }
|
28
41
|
|
29
42
|
before do
|
30
43
|
allow(Google::Auth::UserAuthorizer).
|
31
44
|
to receive(:new) { authorizer }
|
32
45
|
allow(Google::Auth::Stores::InMemoryTokenStore).
|
33
46
|
to receive(:new) { token_store }
|
47
|
+
allow(Gmail::Authenticator::ImapBackupToken).
|
48
|
+
to receive(:new) { token }
|
34
49
|
|
35
50
|
allow(highline).to receive(:ask).and_call_original
|
51
|
+
allow(highline).to receive(:agree).and_call_original
|
36
52
|
|
37
53
|
allow(Kernel).to receive(:system)
|
38
54
|
allow(Kernel).to receive(:puts)
|
39
55
|
|
40
|
-
allow(input).to receive(:gets).and_return(
|
41
|
-
"my_client_id\n",
|
42
|
-
"my_secret\n",
|
43
|
-
"my_code\n"
|
44
|
-
)
|
56
|
+
allow(input).to receive(:gets).and_return(*user_input)
|
45
57
|
end
|
46
58
|
|
47
59
|
describe "#run" do
|
@@ -80,5 +92,30 @@ describe Imap::Backup::Configuration::GmailOauth2 do
|
|
80
92
|
it "includes the client_secret in the credentials" do
|
81
93
|
expect(result).to match('"client_secret":"my_secret"')
|
82
94
|
end
|
95
|
+
|
96
|
+
context "when the account already has client info" do
|
97
|
+
let(:valid) { true }
|
98
|
+
let(:user_input) { %W(yes\n) }
|
99
|
+
|
100
|
+
it "requests confirmation of client info" do
|
101
|
+
expect(highline).to have_received(:agree).with("Use existing client info?")
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when yhe user says 'no'" do
|
105
|
+
let(:user_input) { %W(no\n) }
|
106
|
+
|
107
|
+
it "requests client_id" do
|
108
|
+
expect(highline).to have_received(:ask).with("client_id: ")
|
109
|
+
end
|
110
|
+
|
111
|
+
it "requests client_secret" do
|
112
|
+
expect(highline).to have_received(:ask).with("client_secret: ")
|
113
|
+
end
|
114
|
+
|
115
|
+
it "requests the success code" do
|
116
|
+
expect(highline).to have_received(:ask).with("success code: ")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
83
120
|
end
|
84
121
|
end
|
@@ -43,7 +43,7 @@ describe Imap::Backup::Configuration::Setup do
|
|
43
43
|
describe "main menu" do
|
44
44
|
before { subject.run }
|
45
45
|
|
46
|
-
|
46
|
+
["add account", "save and exit", "exit without saving"].each do |choice|
|
47
47
|
it "includes #{choice}" do
|
48
48
|
expect(output.string).to include(choice)
|
49
49
|
end
|
@@ -12,7 +12,6 @@ describe Imap::Backup::Utils do
|
|
12
12
|
describe ".check_permissions" do
|
13
13
|
let(:requested) { 0o345 }
|
14
14
|
|
15
|
-
# rubocop:disable RSpec/EmptyExampleGroup
|
16
15
|
context "with existing files" do
|
17
16
|
[
|
18
17
|
[0o100, "less than the limit", true],
|
@@ -37,7 +36,6 @@ describe Imap::Backup::Utils do
|
|
37
36
|
end
|
38
37
|
end
|
39
38
|
end
|
40
|
-
# rubocop:enable RSpec/EmptyExampleGroup
|
41
39
|
|
42
40
|
context "with non-existent files" do
|
43
41
|
let(:exists) { false }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imap-backup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Yates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gmail_xoauth
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 3.0.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec_junit_formatter
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rubocop-rspec
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,12 +172,12 @@ executables:
|
|
158
172
|
extensions: []
|
159
173
|
extra_rdoc_files: []
|
160
174
|
files:
|
175
|
+
- ".circleci/config.yml"
|
161
176
|
- ".gitignore"
|
162
177
|
- ".rspec"
|
163
178
|
- ".rspec-all"
|
164
179
|
- ".rubocop.yml"
|
165
180
|
- ".rubocop_todo.yml"
|
166
|
-
- ".travis.yml"
|
167
181
|
- Gemfile
|
168
182
|
- LICENSE
|
169
183
|
- README.md
|
@@ -196,7 +210,7 @@ files:
|
|
196
210
|
- docs/26-type-code-into-imap-backup.png
|
197
211
|
- docs/27-success.png
|
198
212
|
- docs/docker-imap.md
|
199
|
-
- docs/setting-up-gmail.md
|
213
|
+
- docs/setting-up-gmail-with-oauth2.md
|
200
214
|
- imap-backup.gemspec
|
201
215
|
- lib/email/mboxrd/message.rb
|
202
216
|
- lib/email/provider.rb
|
@@ -276,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
290
|
- !ruby/object:Gem::Version
|
277
291
|
version: '0'
|
278
292
|
requirements: []
|
279
|
-
rubygems_version: 3.1.
|
293
|
+
rubygems_version: 3.1.4
|
280
294
|
signing_key:
|
281
295
|
specification_version: 4
|
282
296
|
summary: Backup GMail (or other IMAP) accounts to disk
|
data/.travis.yml
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
services:
|
4
|
-
- docker
|
5
|
-
|
6
|
-
rvm:
|
7
|
-
- 2.4
|
8
|
-
- 2.5
|
9
|
-
- 2.6
|
10
|
-
- 2.7
|
11
|
-
- jruby-19mode
|
12
|
-
|
13
|
-
branches:
|
14
|
-
only:
|
15
|
-
- master
|
16
|
-
|
17
|
-
before_install:
|
18
|
-
- gem update --system
|
19
|
-
- gem update bundler
|
20
|
-
|
21
|
-
script:
|
22
|
-
- docker pull antespi/docker-imap-devel:latest
|
23
|
-
- docker run -d --env MAIL_ADDRESS=address@example.org --env MAIL_PASS=pass --env MAILNAME=example.org --publish 8993:993 antespi/docker-imap-devel:latest
|
24
|
-
- sleep 10
|
25
|
-
- bundle exec rake
|