worochi 0.0.7 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/worochi/agent/{sample.rb → #example.rb} +2 -14
- data/lib/worochi/agent/dropbox.rb +3 -13
- data/lib/worochi/agent/github.rb +8 -23
- data/lib/worochi/agent.rb +46 -18
- data/lib/worochi/config/#example.yml +35 -0
- data/lib/worochi/config/dropbox.yml +14 -0
- data/lib/worochi/config/github.yml +17 -0
- data/lib/worochi/config.rb +9 -84
- data/lib/worochi/configurator.rb +120 -0
- data/lib/worochi/helper/github_helper.rb +111 -0
- data/lib/worochi/helper.rb +28 -7
- data/lib/worochi/item.rb +5 -3
- data/lib/worochi/log.rb +8 -14
- data/lib/worochi/oauth.rb +69 -0
- data/lib/worochi/version.rb +1 -1
- data/lib/worochi.rb +20 -3
- data/spec/cassettes/Worochi/_push/pushes_with_agents.yml +512 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/_push_item/pushes_it_chunked_if_size_exceeds_limit.yml +1049 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/_push_item_chunked/raises_an_error.yml +44 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/_push_items/pushes_multiple_items.yml +165 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/it_should_behave_like_a_service_agent/_files/raises_error_on_invalid_path.yml +38 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/it_should_behave_like_a_service_agent/_files_and_folders/shows_detailed_listing.yml +79 -0
- data/spec/cassettes/Worochi_Agent_Dropbox/it_should_behave_like_a_service_agent/_files_and_folders/shows_detailed_listing_including_the_required_fields.yml +79 -0
- data/spec/cassettes/Worochi_Agent_Github/_list/works_with_absolute_paths.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/_repos/lists_the_repos.yml +207 -0
- data/spec/cassettes/Worochi_Agent_Github/_source_branch/retrieves_the_master_branch_correctly.yml +6 -6
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/accepts_a_different_relative_path.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/contains_file1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/does_not_contain_folder1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files/raises_error_on_invalid_path.yml +133 -0
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files_and_folders/contains_folder1_and_file1.yml +24 -24
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_files_and_folders/shows_detailed_listing_including_the_required_fields.yml +133 -0
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_folders/accepts_a_different_relative_path.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_folders/contains_folder1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/it_should_behave_like_a_service_agent/_folders/does_not_contain_file1.yml +12 -12
- data/spec/cassettes/Worochi_Agent_Github/{_push_all → modifies_the_repo/_push_all}/pushes_a_list_of_items_to_create_a_new_commit.yml +80 -80
- data/spec/cassettes/Worochi_Agent_Github/{_push_all → modifies_the_repo/_push_all}/pushes_the_file_to_the_right_place.yml +60 -60
- data/spec/cassettes/Worochi_Agent_Github/modifies_the_repo/_push_blob/pushes_the_blob_even_when_it_is_larger_than_block_size.yml +181 -0
- data/spec/cassettes/Worochi_Agent_Github/modifies_the_repo/_push_item/pushes_a_single_item_and_makes_a_commit.yml +687 -0
- data/spec/cassettes/Worochi_Agent_Github/modifies_the_repo/_stream_blob/streams_the_file_as_an_Base64_JSON_field.yml +181 -0
- data/spec/cassettes/Worochi_OAuth/_flow_end/rejects_bad_code.yml +56 -0
- data/spec/{helper.rb → spec_helper.rb} +14 -1
- data/spec/support/aws_uri_matcher.rb +1 -1
- data/spec/support/shared_exampes_for_agents.rb +13 -2
- data/spec/support/test_files.rb +4 -4
- data/spec/worochi/agent/dropbox_spec.rb +29 -3
- data/spec/worochi/agent/github_spec.rb +54 -26
- data/spec/worochi/agent_spec.rb +34 -1
- data/spec/worochi/config_spec.rb +46 -30
- data/spec/worochi/helper/github_helper_spec.rb +94 -0
- data/spec/worochi/helper_spec.rb +15 -3
- data/spec/worochi/item_spec.rb +9 -6
- data/spec/worochi/log_spec.rb +30 -0
- data/spec/worochi/oauth_spec.rb +33 -0
- data/spec/worochi_spec.rb +25 -1
- data/worochi.gemspec +5 -1
- metadata +104 -11
- data/lib/worochi/helper/github.rb +0 -100
- data/spec/worochi/helper/github_spec.rb +0 -57
data/lib/worochi/helper.rb
CHANGED
@@ -1,18 +1,34 @@
|
|
1
|
-
require 'aws-sdk' unless Worochi::Config.s3_bucket.nil?
|
2
|
-
|
3
1
|
class Worochi
|
4
2
|
# Contains any global helper methods not specific to any individual service.
|
5
3
|
module Helper
|
6
4
|
class << self
|
7
5
|
# Given an S3 path, return the full URL for the corresponding object
|
8
|
-
# determined using the AWS SDK.
|
6
|
+
# determined using the AWS SDK. AWS_SECRET_ACCESS_KEY and
|
7
|
+
# AWS_ACCESS_KEY_ID should be present in ENV. The string should be
|
8
|
+
# formatted as: `s3:(bucket_name:)path/to/file`.
|
9
9
|
#
|
10
|
-
# @param path [String]
|
11
|
-
# @return [URI::
|
10
|
+
# @param path [String] S3 path
|
11
|
+
# @return [URI::HTTPS] URI of the file on S3
|
12
|
+
# @example Pre-configured bucket name
|
13
|
+
# Worochi::Config.s3_bucket = 'worochi'
|
14
|
+
# Worochi::Helper.s3_url('s3:test/path')
|
15
|
+
# # => #<URI::HTTPS URL:https://worochi.s3.amazonaws.com/test/path?AWSAccessKeyId=...>
|
16
|
+
# @example Custom bucket name
|
17
|
+
# Worochi::Helper.s3_url('s3:bucket-name:a/b')
|
18
|
+
# # => #<URI::HTTPS URL:https://bucket-name.s3.amazonaws.com/a/b?AWSAccessKeyId=...>
|
19
|
+
# @example Invalid syntax
|
20
|
+
# Worochi::Helper.s3_url('www.a.com/b.txt')
|
21
|
+
# # => Worochi::Error
|
12
22
|
def s3_url(path)
|
13
|
-
raise Error, 'S3
|
23
|
+
raise Error, 'Invalid S3 path' unless is_s3_path?(path)
|
14
24
|
path = path.sub(s3_prefix_re, '')
|
15
|
-
|
25
|
+
if match = /^(.*)\:/.match(path)
|
26
|
+
bucket = match[1]
|
27
|
+
path = path.sub(/^(.*)\:/, '')
|
28
|
+
end
|
29
|
+
bucket ||= Config.s3_bucket
|
30
|
+
raise Error, 'S3 bucket name is not defined' if bucket.nil?
|
31
|
+
AWS::S3.new.buckets[bucket].objects[path].url_for(:read)
|
16
32
|
end
|
17
33
|
|
18
34
|
# Check if a given path is an S3 path.
|
@@ -33,4 +49,9 @@ class Worochi
|
|
33
49
|
end
|
34
50
|
end
|
35
51
|
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Load all helpers
|
55
|
+
Dir[File.join(File.dirname(__FILE__), 'helper/[^#]*.rb')].each do |file|
|
56
|
+
require 'worochi/helper/' + File.basename(file, '.rb')
|
36
57
|
end
|
data/lib/worochi/item.rb
CHANGED
@@ -102,8 +102,10 @@ class Worochi
|
|
102
102
|
if File.file?(source)
|
103
103
|
retrieve_local(source)
|
104
104
|
else
|
105
|
-
|
106
|
-
|
105
|
+
if Config.s3_enabled? && Helper.is_s3_path?(source)
|
106
|
+
source = Helper.s3_url(source)
|
107
|
+
end
|
108
|
+
retrieve_remote(source)
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
@@ -118,7 +120,7 @@ class Worochi
|
|
118
120
|
file
|
119
121
|
end
|
120
122
|
|
121
|
-
# Downloads a remote file using
|
123
|
+
# Downloads a remote file using `HTTP::Get`.
|
122
124
|
#
|
123
125
|
# @param file_url [String, URI] the URL of the file
|
124
126
|
# @return [Tempfile] the downloaded file
|
data/lib/worochi/log.rb
CHANGED
@@ -13,8 +13,10 @@ class Worochi
|
|
13
13
|
}
|
14
14
|
class << self
|
15
15
|
# Initializes the logging system.
|
16
|
-
|
17
|
-
|
16
|
+
#
|
17
|
+
# @param logdev [IO] target device to log to
|
18
|
+
def init(logdev=nil)
|
19
|
+
@logger = Logger.new(logdev || Config.logdev)
|
18
20
|
@logger.formatter = proc do |severity, datetime, progname, msg|
|
19
21
|
"[\033[#{SEVERITY_COLOR[severity]}m#{severity}\033[0m]: #{msg}\n"
|
20
22
|
end
|
@@ -22,30 +24,22 @@ class Worochi
|
|
22
24
|
|
23
25
|
# Prints DEBUG messages
|
24
26
|
def debug(message)
|
25
|
-
|
26
|
-
init_log if @logger.nil?
|
27
|
-
@logger.debug message
|
27
|
+
@logger.debug message unless Worochi::Config.silent?
|
28
28
|
end
|
29
29
|
|
30
30
|
# Prints WARN messages
|
31
31
|
def warn(message)
|
32
|
-
|
33
|
-
init_log if @logger.nil?
|
34
|
-
@logger.warn message
|
32
|
+
@logger.warn message unless Worochi::Config.silent?
|
35
33
|
end
|
36
34
|
|
37
35
|
# Prints INFO messages
|
38
36
|
def info(message)
|
39
|
-
|
40
|
-
init_log if @logger.nil?
|
41
|
-
@logger.info message
|
37
|
+
@logger.info message unless Worochi::Config.silent?
|
42
38
|
end
|
43
39
|
|
44
40
|
# Prints ERROR messages
|
45
41
|
def error(message)
|
46
|
-
|
47
|
-
init_log if @logger.nil?
|
48
|
-
@logger.error message
|
42
|
+
@logger.error message unless Worochi::Config.silent?
|
49
43
|
end
|
50
44
|
end
|
51
45
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
|
3
|
+
class Worochi
|
4
|
+
# Implements OAuth2 authorization code flow for obtaining user tokens.
|
5
|
+
class OAuth
|
6
|
+
# OAuth2 options.
|
7
|
+
# @return [Hashie::Mash]
|
8
|
+
attr_accessor :options
|
9
|
+
|
10
|
+
# The OAuth2 client
|
11
|
+
# @return [OAuth2::Client]
|
12
|
+
attr_reader :client
|
13
|
+
|
14
|
+
# @param service [Symbol] service name
|
15
|
+
# @param redirect_url [String] callback URL if required
|
16
|
+
def initialize(service, redirect_uri=nil)
|
17
|
+
@options = Worochi::Config.service_opts(service).oauth
|
18
|
+
options.service = service
|
19
|
+
options.redirect_uri = redirect_uri
|
20
|
+
opts = { site: options.site }
|
21
|
+
opts[:authorize_url] = options.authorize_url if options.authorize_url
|
22
|
+
opts[:token_url] = options.token_url if options.token_url
|
23
|
+
@client = OAuth2::Client.new(id, secret, opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the URL to start the authorization flow.
|
27
|
+
#
|
28
|
+
# @param state [String] optional security verification state
|
29
|
+
# @return [String] URL to begin flow
|
30
|
+
def flow_start(state=nil)
|
31
|
+
client.site = options.site
|
32
|
+
opts = { scope: scope }
|
33
|
+
opts[:state] = state if state
|
34
|
+
opts[:redirect_uri] = options.redirect_uri if options.redirect_uri
|
35
|
+
client.auth_code.authorize_url(opts)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Retrieves the token using the temporary authorization code.
|
39
|
+
#
|
40
|
+
# @param code [String] authorization code from the first part
|
41
|
+
# @return [OAuth2::AccessToken] OAuth2 token
|
42
|
+
def flow_end(code)
|
43
|
+
client.site = options.token_site || options.site
|
44
|
+
opts = {}
|
45
|
+
opts[:redirect_uri] = options.redirect_uri if options.redirect_uri
|
46
|
+
client.auth_code.get_token(code, opts)
|
47
|
+
end
|
48
|
+
|
49
|
+
alias_method :get_token, :flow_end
|
50
|
+
|
51
|
+
private
|
52
|
+
# @return [String] scope
|
53
|
+
def scope
|
54
|
+
options.scope || ''
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [String] environmental variable for client ID
|
58
|
+
def id
|
59
|
+
var = options.id_env || options.service.to_s.upcase + '_ID'
|
60
|
+
ENV[var]
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [String] environmental variable for client secret
|
64
|
+
def secret
|
65
|
+
var = options.secret_env || options.service.to_s.upcase + '_SECRET'
|
66
|
+
ENV[var]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/worochi/version.rb
CHANGED
data/lib/worochi.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'aws-sdk'
|
1
3
|
require 'worochi/config'
|
2
4
|
require 'worochi/error'
|
3
5
|
require 'worochi/log'
|
4
|
-
require 'worochi/helper'
|
5
6
|
require 'worochi/item'
|
6
7
|
require 'worochi/agent'
|
8
|
+
require 'worochi/oauth'
|
9
|
+
require 'worochi/helper'
|
7
10
|
|
8
11
|
# The main class for the gem. This and the {Agent} class are the main
|
9
12
|
# endpoints for interacting with the remote services.
|
@@ -16,6 +19,15 @@ class Worochi
|
|
16
19
|
# @return [Array]
|
17
20
|
attr_reader :agents
|
18
21
|
|
22
|
+
# Initialize configurations and logging.
|
23
|
+
#
|
24
|
+
# @return [nil]
|
25
|
+
def init
|
26
|
+
Config.load_yaml
|
27
|
+
Log.init
|
28
|
+
reset
|
29
|
+
end
|
30
|
+
|
19
31
|
# Creates a new {Worochi::Agent} and adds it to the list of agents
|
20
32
|
# listening to {Worochi.push} requests.
|
21
33
|
#
|
@@ -113,9 +125,14 @@ class Worochi
|
|
113
125
|
# @see Item.open
|
114
126
|
# @see Agent#push
|
115
127
|
def push(origin, opts={})
|
116
|
-
|
128
|
+
if @agents.empty?
|
129
|
+
Log.warn 'No push targets specified'
|
130
|
+
return false
|
131
|
+
end
|
117
132
|
@agents.each { |agent| agent.push(origin, opts) }
|
118
133
|
true
|
119
134
|
end
|
120
135
|
end
|
121
|
-
end
|
136
|
+
end
|
137
|
+
|
138
|
+
Worochi.init
|