dears3 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 74c3e62a041513e6f02777553a05aca66865bc9e
4
- data.tar.gz: 18d8a01ef03ea76d1fa403afc4d69160bac6b911
3
+ metadata.gz: 4744ddc0b3362fc28d2fea6baec07d58463377ca
4
+ data.tar.gz: 7425662978d73e2f15c08ef4a8636d7970555ab9
5
5
  SHA512:
6
- metadata.gz: 8df8690ad22ddfd2368f7702a69e8ff045369ae0c9fb968085c01a74e982ed677dff16b0e17e37401fd64d4da5f731582c1aedf48205c5d57833a8f7ccde8da4
7
- data.tar.gz: 9cef82454ec4703e74bd468285ebc69d7a4f17b34241927e1caebfb3bc3ff0debf12911902ddfc4c610eab4c17ae9fcdccdda312fbd6540cbf33b6b45e87c138
6
+ metadata.gz: 76cd5e1d5b83ca35ea38eae584358bef6ca8a8b4716f557d5c8b968cf6a8f1647d6bfed71c55c3f02c6603d1ed15ae9c43c00e90248ef964873e286837f55276
7
+ data.tar.gz: 10219a8b43a77c44ccd496e8a496e8540db857b38f73a73e3ac2d2f6f97e238750b9fca5b38b0a92c34a50dfbfde0057299030aaba4448a58e3400b29de4e964
data/.aws.json ADDED
@@ -0,0 +1 @@
1
+ {"access_key_id":"AKIAIQEZRNEZX5DG2AEQ","secret_access_key":"BwDssTdj48Fe1o3KDu5VmeoyiuZJmWYlFtHEmq1j"}
data/README.md CHANGED
@@ -6,7 +6,8 @@ Command line tools to mirror your current directory in an AWS bucket.
6
6
 
7
7
  **Installation**
8
8
 
9
- Run `gem install dears3` from the command line. Only works on *NIX systems.
9
+ Run `gem install dears3` from the command line. Only works on *NIX systems for
10
+ now.
10
11
 
11
12
  **AWS Credentials**
12
13
 
@@ -40,25 +41,22 @@ bucket. Any file beginning with "." is ignored. It syncs to arbitary levels of
40
41
  nesting so be careful with symlinks that could cause an infinite loop.
41
42
 
42
43
  The bucket will take the name of the current directory, replacing underscores
43
- with dashes. Note that the bucket's name must conform with DNS requirements if
44
- you plan on publishing it as a website.
44
+ with dashes. If the bucket name is invalid or unavaiable, you will be prompted
45
+ to specify the bucket's name.
45
46
 
46
47
  *Caution: If a bucket with that name already exists and contains files with the
47
- same names as the files in your directory, those files will be overriden without
48
- warning.*
49
-
50
- Run `s3 upload --publish` to publish your uploaded files as a website.
48
+ same names as the files in your directory, those files will be overriden.*
51
49
 
52
50
  **s3 publish**
53
51
 
54
- Publishes the current directory as a website. Directory must already be uploaded
55
- to s3. Run `s3 publish --off` to roll back.
56
-
52
+ Publishes the current directory as a website. Requires at least one file in the
53
+ directory to be uploaded.
57
54
 
58
55
  ## Contributing
59
56
 
60
- 1. Fork it ( https://github.com/[my-github-username]/dears3/fork )
57
+ 1. Fork it ( https://github.com/7imon7ays/dears3/fork )
61
58
  2. Create your feature branch (`git checkout -b my-new-feature`)
62
59
  3. Commit your changes (`git commit -am 'Add some feature'`)
63
60
  4. Push to the branch (`git push origin my-new-feature`)
64
61
  5. Create a new Pull Request
62
+
data/dears3.gemspec CHANGED
@@ -23,5 +23,7 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.6"
25
25
  spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ spec.add_development_dependency "byebug"
26
28
  end
27
29
 
data/lib/dears3.rb CHANGED
@@ -11,7 +11,7 @@ module DearS3
11
11
  end
12
12
  end
13
13
 
14
- require "dears3/auth"
14
+ require "dears3/authentication"
15
15
  require "dears3/client"
16
16
  require "dears3/cli/s3"
17
17
 
@@ -0,0 +1,32 @@
1
+ require 'aws-sdk'
2
+ require 'oj'
3
+ require 'thor'
4
+ require 'singleton'
5
+
6
+ class DearS3::Authentication
7
+ include Singleton
8
+
9
+ # TODO: Give option to upload once without storing credentials.
10
+ def connect
11
+ # TODO: Raise error if no credentials file available
12
+ ::AWS::S3.new aws_credentials
13
+ end
14
+
15
+ def create_credentials_file! credentials
16
+ File.open credentials_path, "w" do |f|
17
+ f.write credentials.to_json
18
+ f.write "\n"
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def aws_credentials
25
+ ::Oj.load File.read credentials_path
26
+ end
27
+
28
+ def credentials_path
29
+ File.expand_path '~/.aws.json'
30
+ end
31
+ end
32
+
@@ -0,0 +1,53 @@
1
+ module DearS3
2
+ class Cli
3
+ class AuthenticationHelper
4
+ include ::Thor::Shell
5
+
6
+ def initialize authentication
7
+ @authentication = authentication
8
+ end
9
+
10
+ def connect
11
+ begin
12
+ authentication.connect
13
+ rescue Errno::ENOENT
14
+ say "Credentials file not found. Please run 's3:auth' to authenticate.", :red
15
+ abort
16
+ end
17
+ end
18
+
19
+ def save_credentials! credentials
20
+ authentication.create_credentials_file! credentials
21
+ end
22
+
23
+ def maybe_get_credentials
24
+ if File.exists?(credentials_path) && !override_credentials?
25
+ nil
26
+ else
27
+ request_credentials
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :authentication
34
+
35
+ def request_credentials
36
+ access_key_id = ask "Please enter your AWS access key id:"
37
+ secret_access_key = ask "Please enter your AWS secret access key:", echo: false
38
+ say
39
+
40
+ { access_key_id: access_key_id, secret_access_key: secret_access_key }
41
+ end
42
+
43
+ def override_credentials?
44
+ choice = ask("Override existing '.aws.json' file? (y/n):")
45
+ %w( y yes Y ok OK ).include? choice
46
+ end
47
+
48
+ def credentials_path
49
+ File.expand_path '~/.aws.json'
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,116 @@
1
+ module DearS3
2
+ class Cli
3
+ class ClientHelper
4
+ include ::Thor::Shell
5
+
6
+ def initialize s3_client
7
+ @s3_client = s3_client
8
+
9
+ name = get_bucket_name
10
+
11
+ s3_client.set_bucket name
12
+ end
13
+
14
+ def upload
15
+ bucket_name = s3_client.bucket_name
16
+
17
+ say "Uploading files to bucket '#{ bucket_name }'."
18
+
19
+ begin
20
+ s3_client.walk_and_upload ".", status_proc
21
+ rescue ::AWS::S3::Errors::Forbidden
22
+ alert_access_denied
23
+ exit
24
+ end
25
+ say "Done syncing bucket."
26
+ end
27
+
28
+ def current_dir_to_bucket_name
29
+ File.basename(Dir.getwd).gsub('_', '-')
30
+ end
31
+
32
+ def publish
33
+ bucket_files = s3_client.files_in_bucket
34
+
35
+ if bucket_files.empty?
36
+ abort "Bucket is empty. Please upload at least one file before publishing"
37
+ end
38
+
39
+ say "Files currently in your bucket:"
40
+ say bucket_files.join(" | "), :green
41
+ index_doc = request_doc "Pick your bucket's index document:"
42
+ error_doc = request_doc "Pick your bucket's error document:"
43
+
44
+ say "Publishing your bucket. This may take a while..."
45
+ bucket_url = s3_client.configure_website index_doc, error_doc
46
+ say "Bucket published at #{ bucket_url }."
47
+ end
48
+
49
+ def unpublish
50
+ bucket_url = s3_client.remove_website
51
+ say "Removed #{ bucket_url } from the web."
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :s3_client
57
+
58
+ def get_bucket_name
59
+ bucket_name = default_bucket_name
60
+
61
+ if s3_client.validate_bucket_name(bucket_name)
62
+ bucket_name = ask "Please select your bucket's name:"
63
+ end
64
+
65
+ while error = s3_client.validate_bucket_name(bucket_name)
66
+ bucket_name = ask "#{ error } bucket name. Please select another:"
67
+ end
68
+
69
+ if s3_client.new_bucket? bucket_name
70
+ choice = ask "Creating new bucket '#{ bucket_name }'. Continue? (y/n/abort)" end
71
+
72
+ return get_bucket_name if %w( n no N No NO ).include? choice
73
+ exit if choice == "abort"
74
+
75
+ bucket_name
76
+ end
77
+
78
+ def default_bucket_name
79
+ File.basename(Dir.getwd).gsub('_', '-').downcase
80
+ end
81
+
82
+ def request_doc request_message
83
+ doc = ask request_message
84
+ files_in_bucket = s3_client.files_in_bucket
85
+
86
+ until files_in_bucket.include? doc
87
+ say "No such file in your bucket. Please choose one from this list:"
88
+ doc = ask files_in_bucket.join(" | ") + "\n", :green
89
+ end
90
+
91
+ doc
92
+ end
93
+
94
+ def alert_access_denied
95
+ say "Access denied!", :red
96
+ say "Make sure your credentials are correct and your bucket name isn't already taken by someone else."
97
+ say "Note: AWS bucket names are shared across all users."
98
+ say
99
+ end
100
+
101
+ def status_proc
102
+ # TODO: Confirm overriding files
103
+ Proc.new do |entry, status|
104
+ case status
105
+ when :unchanged
106
+ say "\tUnchanged: #{ entry }", :blue
107
+ when :update
108
+ say "\tUpdating: '#{ entry }'", :yellow
109
+ when :upload
110
+ say "\tUploading: '#{ entry }'", :green
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
data/lib/dears3/cli/s3.rb CHANGED
@@ -1,39 +1,56 @@
1
+ require 'dears3/cli/authentication_helper'
2
+ require 'dears3/cli/client_helper'
1
3
  require 'thor'
2
4
 
3
5
  module DearS3
4
6
  class Cli
5
- class S3 < Thor
6
- desc "upload", "Deploy current and nested directories to S3"
7
- option :publish, type: :boolean, default: false # Optionally publish to the web
8
- def upload
9
- s3_upload = open_connection
10
-
11
- s3_upload.sync "."
12
- s3_upload.configure_website if options[:publish]
13
- end
7
+ class S3 < Thor
8
+ desc "upload", "Deploy current and nested directories to S3"
9
+ def upload
10
+ client_helper.upload
11
+ end
14
12
 
15
- desc "publish", "Publish bucket as a website"
16
- option :off, type: :boolean, default: false
17
- def publish
18
- s3_upload = open_connection
19
- options[:off] ?
20
- s3_upload.remove_website : s3_upload.configure_website
21
- end
13
+ desc "publish", "Publish bucket as a website"
14
+ def publish
15
+ client_helper.publish
16
+ end
22
17
 
23
- desc "auth", "Save auth credentials in home directory"
24
- def auth
25
- s3_auth = DearS3::Auth.new
26
- s3_auth.authenticate
27
- end
18
+ desc "unpublish", "Take bucket off the www"
19
+ def unpublish
20
+ client_helper.unpublish
21
+ end
28
22
 
29
- private
30
-
31
- def open_connection
32
- s3_auth = DearS3::Auth.new
33
- s3_connection = s3_auth.connect
34
- DearS3::Client.new s3_connection
23
+ desc "auth", "Save AWS credentials in home directory"
24
+ def auth
25
+ # If credentials file already exists and user doesn't
26
+ # choose to override, do nothing.
27
+ if credentials = authentication_helper.maybe_get_credentials
28
+ authentication_helper.save_credentials! credentials
35
29
  end
36
30
  end
31
+
32
+ private
33
+
34
+ def client_helper
35
+ @client_helper ||= ClientHelper.new s3_client
36
+ end
37
+
38
+ def s3_client
39
+ @s3_client ||= DearS3::Client.instance.with s3_connection
40
+ end
41
+
42
+ def s3_connection
43
+ authentication.connect
44
+ end
45
+
46
+ def authentication_helper
47
+ @auhentication_helper ||= DearS3::Cli::AuthenticationHelper.new authentication
48
+ end
49
+
50
+ def authentication
51
+ @authentication ||= DearS3::Authentication.instance
52
+ end
53
+ end
37
54
  end
38
55
  end
39
56
 
data/lib/dears3/client.rb CHANGED
@@ -2,40 +2,81 @@ require 'aws-sdk'
2
2
  require 'thor'
3
3
  require 'digest/md5'
4
4
  require 'mime/types'
5
+ require 'singleton'
5
6
 
6
7
  class DearS3::Client
7
- include ::Thor::Shell
8
+ include Singleton
8
9
 
9
- def initialize s3_connection
10
- @s3 = s3_connection
11
- @bucket = nil
10
+ def set_bucket name
11
+ self.bucket = s3.buckets[name]
12
+
13
+ if new_bucket? name
14
+ s3.buckets.create(bucket.name, acl: :bucket_owner_full_control)
15
+ end
16
+
17
+ bucket.name
18
+ end
19
+
20
+ def validate_bucket_name name
21
+ return :Invalid if invalid_bucket_name? name
22
+ return :Unavailable if unavailable_bucket_name? name
23
+
24
+ nil
25
+ end
26
+
27
+ def new_bucket? name
28
+ !s3.buckets[name].exists?
29
+ end
12
30
 
13
- set_bucket
31
+ def bucket_name
32
+ bucket.name
14
33
  end
15
34
 
16
- def sync path
17
- say "Uploading files to bucket '#{ bucket.name }'."
18
- walk_and_upload path
19
- say "Done syncing bucket."
35
+ def with s3_connection
36
+ @bucket = nil
37
+ @s3 = s3_connection
38
+ self
39
+ end
40
+
41
+ def walk_and_upload path, status_proc = nil
42
+ entries = Dir.entries path
43
+ entries.each do |entry|
44
+ next if entry == File.basename(__FILE__) || entry[0] == '.'
45
+ nested_entry = (path == "." ? entry : "#{ path }/#{ entry }")
46
+ if File.directory? nested_entry
47
+ walk_and_upload nested_entry, status_proc
48
+ next
49
+ else
50
+ upload nested_entry, status_proc
51
+ end
52
+ end
20
53
  end
21
54
 
22
- def configure_website
23
- files = bucket.objects.map { |obj| obj.key }
24
- say "Files currently in your bucket:"
25
- say files.join(" | "), :green
26
- index_doc = ask "Pick your bucket's index document:"
27
- error_doc = ask "Pick your bucket's error document:"
28
- say "Publishing your bucket. This may take a while..."
55
+ def configure_website index_doc, error_doc
29
56
  bucket.configure_website do |cfg|
30
57
  cfg.index_document_suffix = index_doc
31
- cfg.error_document_key = error_doc # TODO: Make this optional
58
+ cfg.error_document_key = error_doc
32
59
  end
33
- say "Bucket published at #{ bucket.url }."
60
+
61
+ bucket.policy = generate_policy
62
+ # TODO: find more general pattern
63
+ "http://#{ bucket_name }.s3-website-us-east-1.amazonaws.com/"
64
+ end
65
+
66
+ def generate_policy
67
+ policy = AWS::S3::Policy.new
68
+ resources = "arn:aws:s3:::#{ bucket_name }/*"
69
+ policy.allow(actions: [:get_object], resources: resources, principals: :any)
70
+ policy
71
+ end
72
+
73
+ def files_in_bucket
74
+ @files_in_bucket ||= bucket.objects.map &:key
34
75
  end
35
76
 
36
77
  def remove_website
37
78
  bucket.remove_website_configuration
38
- say "Removed #{ bucket.name } from the web."
79
+ bucket.url
39
80
  end
40
81
 
41
82
  private
@@ -43,59 +84,53 @@ class DearS3::Client
43
84
  attr_accessor :bucket
44
85
  attr_reader :s3
45
86
 
46
- def set_bucket
47
- # TODO: Optionally configure bucket name and enforce DNS requirements
48
- # see https://forums.aws.amazon.com/thread.jspa?messageID=570880
49
- bucket_name = File.basename(Dir.getwd).gsub '_', '-'
50
- self.bucket = s3.buckets[bucket_name]
87
+ def upload entry, status_proc = nil
88
+ object = bucket.objects[entry]
51
89
 
52
- unless bucket.exists?
53
- say "Creating bucket '#{ bucket.name }'"
54
- s3.buckets.create(bucket.name, acl: :bucket_owner_full_control)
90
+ if object.exists? && entry_is_unchanged?(entry, object)
91
+ status_proc.call entry, :unchanged
92
+ elsif object.exists?
93
+ status_proc.call entry, :update
94
+ else
95
+ status_proc.call entry, :upload
55
96
  end
97
+
98
+ content_type = ::MIME::Types.type_for(entry).to_s
99
+ object.write File.open entry, content_type: content_type
56
100
  end
57
101
 
58
- def walk_and_upload path
59
- entries = Dir.entries path
60
- entries.each do |entry|
61
- next if entry == File.basename(__FILE__) || entry[0] == '.'
62
- nested_entry = (path == "." ? entry : "#{ path }/#{ entry }")
63
- if File.directory? nested_entry
64
- walk_and_upload nested_entry
65
- next
66
- else
67
- upload nested_entry
68
- end
69
- end
102
+ def entry_is_unchanged? entry, object
103
+ # Is object etag equal to the MD5 digest of the entry?
104
+ # Strip opening and closing "\" chars from AWS-formatted etag
105
+ object.etag[1..-2] == ::Digest::MD5.hexdigest(File.read entry)
70
106
  end
71
107
 
72
- def upload entry
73
- new_object = bucket.objects[entry]
108
+ def invalid_bucket_name? name
109
+ name.length < 3 or
110
+ name.length > 62 or
111
+ name[-1] == '-' or
112
+ name.include?(".") or
113
+ name.include?(";") or
114
+ name.include?("-.") or
115
+ name.include?(".-")
116
+ end
117
+
118
+ def unavailable_bucket_name? name
119
+ # Try deleting a non-existent object
120
+ # If the action is forbidden, the bucket exists and is taken
121
+ forbidden_exceptions = [AWS::S3::Errors::AccessDenied,
122
+ AWS::S3::Errors::Forbidden]
74
123
 
124
+ rand_key = (0...20).map { ('a'..'z').to_a[rand(26)] }.join
75
125
  begin
76
- if new_object.exists?
77
- # Strip opening and closing "\" chars from AWS-formatted etag
78
- etag_is_same = new_object.etag[1..-2] == ::Digest::MD5.hexdigest(File.read entry)
79
-
80
- if etag_is_same
81
- say "\tUnchanged: #{ entry }", :blue
82
- return
83
- else
84
- # TODO: Confirm overriding files
85
- say "\tUpdating: '#{ entry }'", :yellow
86
- end
87
- else
88
- say "\tUploading: '#{ entry }'", :green
89
- end
90
- content_type = ::MIME::Types.type_for(entry).to_s
91
- new_object.write File.open entry, content_type: content_type
92
- rescue ::AWS::S3::Errors::Forbidden
93
- say "Access denied!", :red
94
- say "Make sure your credentials are correct and your bucket name isn't already taken by someone else."
95
- say "Note: AWS bucket names are shared across all users."
96
- say
97
- abort
126
+ s3.buckets[name].objects[rand_key].delete
127
+ rescue *forbidden_exceptions
128
+ return true
129
+ rescue AWS::S3::Errors::NoSuchBucket
130
+ return false
98
131
  end
132
+
133
+ false
99
134
  end
100
135
  end
101
136
 
@@ -1,3 +1,3 @@
1
1
  module DearS3
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe DearS3::Cli::S3 do
4
+ context "auth" do
5
+ let(:auth_output) do
6
+ capture(:stdout) { subject.auth }
7
+ end
8
+
9
+ it 'Confirms with the user before overriding an existing credentials file' do
10
+ File.any_instance.stub(exists?: true)
11
+ Thor::Shell::Basic.any_instance.stub(ask: 'y')
12
+ auth_output.should include "Override existing '.aws.json'?"
13
+ auth_output.should include "Please enter your AWS access key id:"
14
+ auth_output.should include "Please enter your AWS secret access key:"
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe DearS3::Cli::S3 do
4
+ context "publishing" do
5
+ let(:output_after_publish) { capture(:stdout) { subject.publish } }
6
+
7
+ it 'prompts user for index and error document before publishing' do
8
+ Thor::Shell::Basic.any_instance.stub(ask: 'foobar')
9
+ output_after_publish.should include "Files currently in your bucket"
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,24 @@
1
+ require 'rspec'
2
+ require 'bundler/setup'
3
+ require 'thor'
4
+
5
+ Bundler.setup
6
+
7
+ require 'dears3'
8
+
9
+ #AWS.stub!
10
+ RSpec.configure do |config|
11
+ def capture(stream)
12
+ begin
13
+ stream = stream.to_s
14
+ eval "$#{stream} = StringIO.new"
15
+ yield
16
+ result = eval("$#{stream}").string
17
+ ensure
18
+ eval("$#{stream} = #{stream.upcase}")
19
+ end
20
+
21
+ result
22
+ end
23
+ end
24
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dears3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 7imon7ays
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-08 00:00:00.000000000 Z
11
+ date: 2014-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: byebug
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description:
98
126
  email:
99
127
  executables:
@@ -101,6 +129,7 @@ executables:
101
129
  extensions: []
102
130
  extra_rdoc_files: []
103
131
  files:
132
+ - ".aws.json"
104
133
  - Gemfile
105
134
  - LICENSE.txt
106
135
  - README.md
@@ -108,10 +137,15 @@ files:
108
137
  - bin/s3
109
138
  - dears3.gemspec
110
139
  - lib/dears3.rb
111
- - lib/dears3/auth.rb
140
+ - lib/dears3/authentication.rb
141
+ - lib/dears3/cli/authentication_helper.rb
142
+ - lib/dears3/cli/client_helper.rb
112
143
  - lib/dears3/cli/s3.rb
113
144
  - lib/dears3/client.rb
114
145
  - lib/dears3/version.rb
146
+ - spec/authentication_spec.rb
147
+ - spec/client_spec.rb
148
+ - spec/spec_helper.rb
115
149
  homepage: https://github.com/7imon7ays/DearS3
116
150
  licenses:
117
151
  - MIT
@@ -136,4 +170,7 @@ rubygems_version: 2.2.2
136
170
  signing_key:
137
171
  specification_version: 4
138
172
  summary: Sync an S3 bucket with your current directory.
139
- test_files: []
173
+ test_files:
174
+ - spec/authentication_spec.rb
175
+ - spec/client_spec.rb
176
+ - spec/spec_helper.rb
data/lib/dears3/auth.rb DELETED
@@ -1,64 +0,0 @@
1
- require 'aws-sdk'
2
- require 'oj'
3
- require 'thor'
4
-
5
- class DearS3::Auth
6
- include ::Thor::Shell
7
-
8
- def initialize
9
- @credentials = {}
10
- end
11
-
12
- # TODO: Give option to upload once without storing credentials.
13
- def connect
14
- begin
15
- return ::AWS::S3.new aws_credentials
16
- rescue Errno::ENOENT
17
- say "Credentials file not found. Please run 's3:auth' to authenticate.", :red
18
- abort
19
- end
20
- end
21
-
22
- def authenticate
23
- if confirm_create_credentials_file?
24
- request_credentials
25
- create_credentials_file!
26
- end
27
- end
28
-
29
- private
30
-
31
- def aws_credentials
32
- ::Oj.load File.read credentials_path
33
- end
34
-
35
- def create_credentials_file!
36
- File.open credentials_path, "w" do |f|
37
- f.write @credentials.to_json
38
- f.write "\n"
39
- end
40
- end
41
-
42
- def request_credentials
43
- @credentials[:access_key_id] = ask "Please enter your AWS access key id:"
44
- @credentials[:secret_access_key] = ask(
45
- "Please enter your AWS secret access key:",
46
- echo: false
47
- )
48
- say
49
- end
50
-
51
- def credentials_path
52
- File.expand_path "~/.aws.json"
53
- end
54
-
55
- def confirm_create_credentials_file?
56
- if File.exists? credentials_path
57
- override = ask "Override existing '.aws.json' file? (y/n):"
58
- override == "y"
59
- else
60
- true
61
- end
62
- end
63
- end
64
-